From 4b56446e40cfb735e1135744c8c6c40900a32f14 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Wed, 12 Mar 2014 11:50:05 +0100 Subject: [PATCH] Introduce SmackException SmackException (and it's subclasses) is for all errors/exceptions not defined by any XMPP specification. XMPPException is now an abstract class for all errors defined by the XMPP specifications. Methods that involve an IQ exchange now either return the result, which is obtained by IQ response, or they throw an XMPPErrorException if an IQ error was the result of the IQ set/get. If there was no response from the server within the default packet timeout, a NoResponseException will be thrown. XMPP SASL errors are now also reported accordingly. SMACK-426 --- .../jivesoftware/smack/BOSHConnection.java | 37 +- .../jivesoftware/smack/BOSHPacketReader.java | 9 +- .../jivesoftware/smack/AccountManager.java | 116 +++---- .../jivesoftware/smack/PacketCollector.java | 16 +- .../smack/ReconnectionManager.java | 18 +- .../java/org/jivesoftware/smack/Roster.java | 74 ++-- .../org/jivesoftware/smack/RosterGroup.java | 12 +- .../smack/SASLAuthentication.java | 257 +++++++------- .../org/jivesoftware/smack/SmackError.java | 40 --- .../jivesoftware/smack/SmackException.java | 159 +++++++++ .../jivesoftware/smack/XMPPConnection.java | 40 ++- .../org/jivesoftware/smack/XMPPException.java | 236 ++++++------- .../jivesoftware/smack/packet/XMPPError.java | 13 +- .../jivesoftware/smack/sasl/SASLError.java | 45 +++ .../smack/sasl/SASLErrorException.java | 59 ++++ .../smack/sasl/SASLGSSAPIMechanism.java | 7 +- .../smack/sasl/SASLMechanism.java | 54 +-- .../smack/util/PacketParserUtils.java | 6 +- .../smack/ChatConnectionTest.java | 2 +- .../jivesoftware/smack/DummyConnection.java | 2 +- .../org/jivesoftware/smack/RosterTest.java | 3 +- .../smack/RosterVersioningTest.java | 8 +- .../smack/parsing/ParsingExceptionTest.java | 4 +- .../smackx/carbons/CarbonManager.java | 31 +- .../address/MultipleRecipientManager.java | 122 +++---- .../smackx/amp/AMPDeliverCondition.java | 8 +- .../smackx/amp/AMPExpireAtCondition.java | 8 +- .../jivesoftware/smackx/amp/AMPManager.java | 15 +- .../smackx/amp/AMPMatchResourceCondition.java | 8 +- .../smackx/bookmarks/BookmarkManager.java | 56 +-- .../smackx/bytestreams/BytestreamManager.java | 5 +- .../smackx/bytestreams/BytestreamRequest.java | 10 +- .../ibb/InBandBytestreamManager.java | 11 +- .../ibb/InBandBytestreamRequest.java | 4 +- .../ibb/InBandBytestreamSession.java | 13 +- .../socks5/Socks5BytestreamManager.java | 43 ++- .../socks5/Socks5BytestreamRequest.java | 14 +- .../bytestreams/socks5/Socks5Client.java | 101 +++--- .../socks5/Socks5ClientForInitiator.java | 22 +- .../bytestreams/socks5/Socks5Proxy.java | 12 +- .../bytestreams/socks5/Socks5Utils.java | 8 +- .../smackx/caps/EntityCapsManager.java | 11 +- .../caps/provider/CapsExtensionProvider.java | 12 +- .../smackx/commands/AdHocCommand.java | 23 +- .../smackx/commands/AdHocCommandManager.java | 30 +- .../smackx/commands/RemoteCommand.java | 25 +- .../smackx/disco/ServiceDiscoveryManager.java | 46 +-- .../filetransfer/FaultTolerantNegotiator.java | 21 +- .../smackx/filetransfer/FileTransfer.java | 10 +- .../filetransfer/FileTransferNegotiator.java | 27 +- .../filetransfer/IBBTransferNegotiator.java | 13 +- .../filetransfer/IncomingFileTransfer.java | 49 ++- .../filetransfer/OutgoingFileTransfer.java | 41 ++- .../Socks5TransferNegotiator.java | 21 +- .../smackx/filetransfer/StreamNegotiator.java | 26 +- .../smackx/iqlast/LastActivityManager.java | 12 +- .../smackx/iqlast/packet/LastActivity.java | 26 +- .../smackx/iqprivate/PrivateDataManager.java | 14 +- .../smackx/muc/MultiUserChat.java | 320 ++++++++++-------- .../smackx/offline/OfflineMessageManager.java | 41 ++- .../jivesoftware/smackx/ping/PingManager.java | 32 +- .../smackx/privacy/PrivacyListManager.java | 87 +++-- .../jivesoftware/smackx/pubsub/LeafNode.java | 84 +++-- .../org/jivesoftware/smackx/pubsub/Node.java | 70 ++-- .../smackx/pubsub/PubSubManager.java | 83 +++-- .../receipts/DeliveryReceiptManager.java | 14 +- .../smackx/search/UserSearch.java | 21 +- .../smackx/search/UserSearchManager.java | 17 +- .../sharedgroups/SharedGroupManager.java | 7 +- .../smackx/time/EntityTimeManager.java | 7 +- .../smackx/vcardtemp/VCardManager.java | 8 +- .../smackx/vcardtemp/packet/VCard.java | 18 +- .../smackx/xhtmlim/XHTMLManager.java | 24 +- .../ibb/InBandBytestreamManagerTest.java | 13 +- .../InBandBytestreamSessionMessageTest.java | 4 +- .../ibb/InBandBytestreamSessionTest.java | 4 +- .../socks5/Socks5ByteStreamManagerTest.java | 23 +- .../socks5/Socks5ByteStreamRequestTest.java | 11 +- .../socks5/Socks5ClientForInitiatorTest.java | 11 +- .../bytestreams/socks5/Socks5ClientTest.java | 14 +- .../bytestreams/socks5/Socks5TestProxy.java | 10 +- .../jivesoftware/smackx/ping/PingTest.java | 42 ++- .../smackx/pubsub/ConfigureFormTest.java | 10 +- .../jivesoftware/util/ConnectionUtils.java | 10 +- .../smackx/jingle/ContentNegotiator.java | 3 +- .../smackx/jingle/JingleManager.java | 18 +- .../smackx/jingle/JingleNegotiator.java | 3 +- .../smackx/jingle/JingleSession.java | 12 +- .../smackx/jingle/JingleSessionRequest.java | 4 +- .../smackx/jingle/JingleSessionState.java | 3 +- .../jingle/JingleSessionStateUnknown.java | 6 +- .../smackx/jingle/nat/BridgedResolver.java | 6 +- .../smackx/jingle/nat/ICEResolver.java | 4 +- .../jingle/nat/ICETransportManager.java | 5 +- .../jingle/nat/JingleTransportManager.java | 5 +- .../smackx/jingle/nat/RTPBridge.java | 25 +- .../jivesoftware/smackx/jingle/nat/STUN.java | 43 ++- .../jingle/nat/STUNTransportManager.java | 2 +- .../jingle/nat/TransportNegotiator.java | 15 +- .../smackx/jingle/nat/TransportResolver.java | 8 +- .../jingle/provider/JingleProvider.java | 6 +- .../smackx/workgroup/agent/Agent.java | 15 +- .../smackx/workgroup/agent/AgentSession.java | 99 ++++-- .../workgroup/agent/TranscriptManager.java | 13 +- .../agent/TranscriptSearchManager.java | 13 +- .../smackx/workgroup/user/Workgroup.java | 68 ++-- .../org/jivesoftware/smack/PacketReader.java | 28 +- .../org/jivesoftware/smack/TCPConnection.java | 81 ++--- .../jivesoftware/smack/RosterOfflineTest.java | 54 +-- 109 files changed, 2040 insertions(+), 1599 deletions(-) delete mode 100644 core/src/main/java/org/jivesoftware/smack/SmackError.java create mode 100644 core/src/main/java/org/jivesoftware/smack/SmackException.java create mode 100644 core/src/main/java/org/jivesoftware/smack/sasl/SASLError.java create mode 100644 core/src/main/java/org/jivesoftware/smack/sasl/SASLErrorException.java diff --git a/bosh/src/main/java/org/jivesoftware/smack/BOSHConnection.java b/bosh/src/main/java/org/jivesoftware/smack/BOSHConnection.java index 5a0b8d3bc..bbbe206e7 100644 --- a/bosh/src/main/java/org/jivesoftware/smack/BOSHConnection.java +++ b/bosh/src/main/java/org/jivesoftware/smack/BOSHConnection.java @@ -22,6 +22,11 @@ import java.io.PipedReader; import java.io.PipedWriter; import java.io.Writer; +import javax.security.sasl.SaslException; + +import org.jivesoftware.smack.SmackException.NotConnectedException; +import org.jivesoftware.smack.SmackException.AlreadyLoggedInException; +import org.jivesoftware.smack.SmackException.ConnectionException; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.ConnectionCreationListener; import org.jivesoftware.smack.ConnectionListener; @@ -29,9 +34,7 @@ import org.jivesoftware.smack.Roster; import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.packet.Packet; import org.jivesoftware.smack.packet.Presence; -import org.jivesoftware.smack.packet.XMPPError; import org.jivesoftware.smack.util.StringUtils; - import org.igniterealtime.jbosh.BOSHClient; import org.igniterealtime.jbosh.BOSHClientConfig; import org.igniterealtime.jbosh.BOSHClientConnEvent; @@ -134,7 +137,7 @@ public class BOSHConnection extends XMPPConnection { this.config = config; } - public void connect() throws XMPPException { + public void connect() throws SmackException { if (connected) { throw new IllegalStateException("Already connected to a server."); } @@ -179,7 +182,7 @@ public class BOSHConnection extends XMPPConnection { .setAttribute(BodyQName.createWithPrefix(XMPP_BOSH_NS, "version", "xmpp"), "1.0") .build()); } catch (Exception e) { - throw new XMPPException("Can't connect to " + getServiceName(), e); + throw new ConnectionException(e); } // Wait for the response from the server @@ -197,9 +200,7 @@ public class BOSHConnection extends XMPPConnection { done = true; String errorMessage = "Timeout reached for the connection to " + getHost() + ":" + getPort() + "."; - throw new XMPPException( - errorMessage, - new XMPPError(XMPPError.Condition.remote_server_timeout, errorMessage)); + throw new SmackException(errorMessage); } } @@ -213,7 +214,7 @@ public class BOSHConnection extends XMPPConnection { } } - public Roster getRoster() { + public Roster getRoster() throws XMPPException, SmackException { if (roster == null) { return null; } @@ -276,12 +277,12 @@ public class BOSHConnection extends XMPPConnection { } public void login(String username, String password, String resource) - throws XMPPException { + throws XMPPException, SmackException, IOException { if (!isConnected()) { - throw new IllegalStateException("Not connected to server."); + throw new NotConnectedException(); } if (authenticated) { - throw new IllegalStateException("Already logged in to server."); + throw new AlreadyLoggedInException(); } // Do partial version of nameprep on the username. username = username.toLowerCase().trim(); @@ -295,7 +296,7 @@ public class BOSHConnection extends XMPPConnection { response = saslAuthentication.authenticate(resource, config.getCallbackHandler()); } } else { - throw new XMPPException("No non-anonymous SASL authentication mechanism available"); + throw new SaslException("No non-anonymous SASL authentication mechanism available"); } // Set the user. @@ -338,12 +339,12 @@ public class BOSHConnection extends XMPPConnection { } } - public void loginAnonymously() throws XMPPException { - if (!isConnected()) { - throw new IllegalStateException("Not connected to server."); + public void loginAnonymously() throws XMPPException, SmackException, IOException { + if (!isConnected()) { + throw new NotConnectedException(); } if (authenticated) { - throw new IllegalStateException("Already logged in to server."); + throw new AlreadyLoggedInException(); } String response; @@ -352,7 +353,7 @@ public class BOSHConnection extends XMPPConnection { } else { // Authenticate using Non-SASL - throw new XMPPException("No anonymous SASL authentication mechanism available"); + throw new SaslException("No anonymous SASL authentication mechanism available"); } // Set the user value. @@ -666,7 +667,7 @@ public class BOSHConnection extends XMPPConnection { listener.reconnectionSuccessful(); } } - catch (XMPPException e) { + catch (Exception e) { for (ConnectionListener listener : getConnectionListeners()) { listener.reconnectionFailed(e); } diff --git a/bosh/src/main/java/org/jivesoftware/smack/BOSHPacketReader.java b/bosh/src/main/java/org/jivesoftware/smack/BOSHPacketReader.java index 91aeaab33..ba8a21b1a 100644 --- a/bosh/src/main/java/org/jivesoftware/smack/BOSHPacketReader.java +++ b/bosh/src/main/java/org/jivesoftware/smack/BOSHPacketReader.java @@ -20,9 +20,10 @@ package org.jivesoftware.smack; import java.io.StringReader; import org.jivesoftware.smack.sasl.SASLMechanism.Challenge; -import org.jivesoftware.smack.sasl.SASLMechanism.Failure; +import org.jivesoftware.smack.sasl.SASLMechanism.SASLFailure; import org.jivesoftware.smack.sasl.SASLMechanism.Success; import org.jivesoftware.smack.util.PacketParserUtils; +import org.jivesoftware.smack.XMPPException.StreamErrorException; import org.xmlpull.v1.XmlPullParserFactory; import org.xmlpull.v1.XmlPullParser; import org.igniterealtime.jbosh.AbstractBody; @@ -106,12 +107,12 @@ public class BOSHPacketReader implements BOSHClientResponseListener { parseFeatures(parser); } else if (parser.getName().equals("failure")) { if ("urn:ietf:params:xml:ns:xmpp-sasl".equals(parser.getNamespace(null))) { - final Failure failure = PacketParserUtils.parseSASLFailure(parser); - connection.getSASLAuthentication().authenticationFailed(failure.getCondition()); + final SASLFailure failure = PacketParserUtils.parseSASLFailure(parser); + connection.getSASLAuthentication().authenticationFailed(failure); connection.processPacket(failure); } } else if (parser.getName().equals("error")) { - throw new XMPPException(PacketParserUtils.parseStreamError(parser)); + throw new StreamErrorException(PacketParserUtils.parseStreamError(parser)); } } } while (eventType != XmlPullParser.END_DOCUMENT); diff --git a/core/src/main/java/org/jivesoftware/smack/AccountManager.java b/core/src/main/java/org/jivesoftware/smack/AccountManager.java index 9cf1b19e4..3f86cb7e0 100644 --- a/core/src/main/java/org/jivesoftware/smack/AccountManager.java +++ b/core/src/main/java/org/jivesoftware/smack/AccountManager.java @@ -21,9 +21,9 @@ import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Map; -import java.util.logging.Level; -import java.util.logging.Logger; +import org.jivesoftware.smack.SmackException.NoResponseException; +import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.Registration; import org.jivesoftware.smack.util.StringUtils; @@ -35,8 +35,6 @@ import org.jivesoftware.smack.util.StringUtils; * @author Matt Tucker */ public class AccountManager { - private static final Logger LOGGER = Logger.getLogger(AccountManager.class.getName()); - private XMPPConnection connection; private Registration info = null; @@ -74,8 +72,10 @@ public class AccountManager { * behavior is to only create new accounts before having logged in to a server. * * @return true if the server support creating new accounts. + * @throws XMPPErrorException + * @throws NoResponseException */ - public boolean supportsAccountCreation() { + public boolean supportsAccountCreation() throws NoResponseException, XMPPErrorException { // Check if we already know that the server supports creating new accounts if (accountCreationSupported) { return true; @@ -83,16 +83,11 @@ public class AccountManager { // No information is known yet (e.g. no stream feature was received from the server // indicating that it supports creating new accounts) so send an IQ packet as a way // to discover if this feature is supported - try { - if (info == null) { - getRegistrationInfo(); - accountCreationSupported = info.getType() != IQ.Type.ERROR; - } - return accountCreationSupported; - } - catch (XMPPException xe) { - return false; + if (info == null) { + getRegistrationInfo(); + accountCreationSupported = info.getType() != IQ.Type.ERROR; } + return accountCreationSupported; } /** @@ -118,21 +113,19 @@ public class AccountManager { * the user's email address. * * @return the required account attributes. + * @throws XMPPErrorException + * @throws NoResponseException */ - public Collection getAccountAttributes() { - try { - if (info == null) { - getRegistrationInfo(); - } - Map attributes = info.getAttributes(); - if (attributes != null) { - return Collections.unmodifiableSet(attributes.keySet()); - } + public Collection getAccountAttributes() throws NoResponseException, XMPPErrorException { + if (info == null) { + getRegistrationInfo(); } - catch (XMPPException xe) { - LOGGER.log(Level.SEVERE, "Error retrieving account attributes from server", xe); + Map attributes = info.getAttributes(); + if (attributes != null) { + return Collections.unmodifiableSet(attributes.keySet()); + } else { + return Collections.emptySet(); } - return Collections.emptySet(); } /** @@ -142,18 +135,14 @@ public class AccountManager { * @param name the name of the account attribute to return its value. * @return the value of the account attribute or null if an account * attribute wasn't found for the requested name. + * @throws XMPPErrorException + * @throws NoResponseException */ - public String getAccountAttribute(String name) { - try { - if (info == null) { - getRegistrationInfo(); - } - return info.getAttributes().get(name); + public String getAccountAttribute(String name) throws NoResponseException, XMPPErrorException { + if (info == null) { + getRegistrationInfo(); } - catch (XMPPException xe) { - LOGGER.log(Level.SEVERE, "Error retrieving account attribute " + name + " info from server", xe); - } - return null; + return info.getAttributes().get(name); } /** @@ -162,18 +151,14 @@ public class AccountManager { * that will complete the registration process. * * @return the account creation instructions, or null if there are none. + * @throws XMPPErrorException + * @throws NoResponseException */ - public String getAccountInstructions() { - try { - if (info == null) { - getRegistrationInfo(); - } - return info.getInstructions(); - } - catch (XMPPException xe) { - LOGGER.log(Level.SEVERE, "Error retrieving account instructions from server", xe); - return null; + public String getAccountInstructions() throws NoResponseException, XMPPErrorException { + if (info == null) { + getRegistrationInfo(); } + return info.getInstructions(); } /** @@ -186,12 +171,10 @@ public class AccountManager { * * @param username the username. * @param password the password. - * @throws XMPPException if an error occurs creating the account. + * @throws XMPPErrorException + * @throws NoResponseException */ - public void createAccount(String username, String password) throws XMPPException { - if (!supportsAccountCreation()) { - throw new XMPPException("Server does not support account creation."); - } + public void createAccount(String username, String password) throws NoResponseException, XMPPErrorException { // Create a map for all the required attributes, but give them blank values. Map attributes = new HashMap(); for (String attributeName : getAccountAttributes()) { @@ -208,20 +191,17 @@ public class AccountManager { * @param username the username. * @param password the password. * @param attributes the account attributes. - * @throws XMPPException if an error occurs creating the account. + * @throws XMPPErrorException if an error occurs creating the account. + * @throws NoResponseException if there was no response from the server. * @see #getAccountAttributes() */ public void createAccount(String username, String password, Map attributes) - throws XMPPException - { - if (!supportsAccountCreation()) { - throw new XMPPException("Server does not support account creation."); - } + throws NoResponseException, XMPPErrorException { Registration reg = new Registration(); reg.setType(IQ.Type.SET); reg.setTo(connection.getServiceName()); - attributes.put("username",username); - attributes.put("password",password); + attributes.put("username", username); + attributes.put("password", password); reg.setAttributes(attributes); connection.createPacketCollectorAndSend(reg).nextResultOrThrow(); } @@ -232,9 +212,10 @@ public class AccountManager { * support changing passwords; an XMPPException will be thrown when that is the case. * * @throws IllegalStateException if not currently logged-in to the server. - * @throws XMPPException if an error occurs when changing the password. + * @throws XMPPErrorException if an error occurs when changing the password. + * @throws NoResponseException if there was no response from the server. */ - public void changePassword(String newPassword) throws XMPPException { + public void changePassword(String newPassword) throws NoResponseException, XMPPErrorException { Registration reg = new Registration(); reg.setType(IQ.Type.SET); reg.setTo(connection.getServiceName()); @@ -251,12 +232,10 @@ public class AccountManager { * support deleting accounts; an XMPPException will be thrown when that is the case. * * @throws IllegalStateException if not currently logged-in to the server. - * @throws XMPPException if an error occurs when deleting the account. + * @throws XMPPErrorException if an error occurs when deleting the account. + * @throws NoResponseException if there was no response from the server. */ - public void deleteAccount() throws XMPPException { - if (!connection.isAuthenticated()) { - throw new IllegalStateException("Must be logged in to delete a account."); - } + public void deleteAccount() throws NoResponseException, XMPPErrorException { Registration reg = new Registration(); reg.setType(IQ.Type.SET); reg.setTo(connection.getServiceName()); @@ -269,10 +248,13 @@ public class AccountManager { /** * Gets the account registration info from the server. + * @throws XMPPErrorException + * @throws NoResponseException * * @throws XMPPException if an error occurs. + * @throws SmackException if there was no response from the server. */ - private synchronized void getRegistrationInfo() throws XMPPException { + private synchronized void getRegistrationInfo() throws NoResponseException, XMPPErrorException { Registration reg = new Registration(); reg.setTo(connection.getServiceName()); info = (Registration) connection.createPacketCollectorAndSend(reg).nextResultOrThrow(); diff --git a/core/src/main/java/org/jivesoftware/smack/PacketCollector.java b/core/src/main/java/org/jivesoftware/smack/PacketCollector.java index 718f8e38e..d402f6db0 100644 --- a/core/src/main/java/org/jivesoftware/smack/PacketCollector.java +++ b/core/src/main/java/org/jivesoftware/smack/PacketCollector.java @@ -20,6 +20,8 @@ package org.jivesoftware.smack; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.TimeUnit; +import org.jivesoftware.smack.SmackException.NoResponseException; +import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.filter.PacketFilter; import org.jivesoftware.smack.packet.Packet; import org.jivesoftware.smack.packet.XMPPError; @@ -152,9 +154,10 @@ public class PacketCollector { * null will be returned. This method does also cancel the PacketCollector. * * @return the next available packet. - * @throws XMPPException + * @throws XMPPErrorException in case an error response. + * @throws NoResponseException if there was no response from the server. */ - public Packet nextResultOrThrow() throws XMPPException { + public Packet nextResultOrThrow() throws NoResponseException, XMPPErrorException { return nextResultOrThrow(connection.getPacketReplyTimeout()); } @@ -164,18 +167,19 @@ public class PacketCollector { * * @param timeout the amount of time to wait for the next packet (in milleseconds). * @return the next available packet. - * @throws XMPPException in case of no response or error response + * @throws NoResponseException if there was no response from the server. + * @throws XMPPErrorException in case an error response. */ - public Packet nextResultOrThrow(long timeout) throws XMPPException { + public Packet nextResultOrThrow(long timeout) throws NoResponseException, XMPPErrorException { Packet result = nextResult(timeout); cancel(); if (result == null) { - throw new XMPPException(SmackError.NO_RESPONSE_FROM_SERVER); + throw new NoResponseException(); } XMPPError xmppError = result.getError(); if (xmppError != null) { - throw new XMPPException(xmppError); + throw new XMPPErrorException(xmppError); } return result; diff --git a/core/src/main/java/org/jivesoftware/smack/ReconnectionManager.java b/core/src/main/java/org/jivesoftware/smack/ReconnectionManager.java index e43fabee6..a2ae412a4 100644 --- a/core/src/main/java/org/jivesoftware/smack/ReconnectionManager.java +++ b/core/src/main/java/org/jivesoftware/smack/ReconnectionManager.java @@ -16,7 +16,9 @@ */ package org.jivesoftware.smack; +import org.jivesoftware.smack.XMPPException.StreamErrorException; import org.jivesoftware.smack.packet.StreamError; + import java.util.Random; import java.util.logging.Logger; /** @@ -146,7 +148,7 @@ public class ReconnectionManager implements ConnectionListener { connection.connect(); } } - catch (XMPPException e) { + catch (Exception e) { // Fires the failed reconnection notification ReconnectionManager.this.notifyReconnectionFailed(e); } @@ -191,17 +193,13 @@ public class ReconnectionManager implements ConnectionListener { public void connectionClosedOnError(Exception e) { done = false; - if (e instanceof XMPPException) { - XMPPException xmppEx = (XMPPException) e; + if (e instanceof StreamErrorException) { + StreamErrorException xmppEx = (StreamErrorException) e; StreamError error = xmppEx.getStreamError(); + String reason = error.getCode(); - // Make sure the error is not null - if (error != null) { - String reason = error.getCode(); - - if ("conflict".equals(reason)) { - return; - } + if ("conflict".equals(reason)) { + return; } } diff --git a/core/src/main/java/org/jivesoftware/smack/Roster.java b/core/src/main/java/org/jivesoftware/smack/Roster.java index cc33b0c22..e7adb5599 100644 --- a/core/src/main/java/org/jivesoftware/smack/Roster.java +++ b/core/src/main/java/org/jivesoftware/smack/Roster.java @@ -30,6 +30,9 @@ import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; +import org.jivesoftware.smack.SmackException.NoResponseException; +import org.jivesoftware.smack.SmackException.NotLoggedInException; +import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.filter.IQReplyFilter; import org.jivesoftware.smack.filter.PacketFilter; import org.jivesoftware.smack.filter.PacketTypeFilter; @@ -186,17 +189,19 @@ public class Roster { * Reloads the entire roster from the server. This is an asynchronous operation, * which means the method will return immediately, and the roster will be * reloaded at a later point when the server responds to the reload request. - * - * @throws IllegalStateException if connection is not logged in or logged in anonymously + * + * @throws SmackException If not logged in. + * @throws IllegalStateException if logged in anonymously */ - public void reload() { + public void reload() throws XMPPException, SmackException { if (!connection.isAuthenticated()) { - throw new IllegalStateException("Not logged in to server."); + throw new NotLoggedInException(); } if (connection.isAnonymous()) { throw new IllegalStateException("Anonymous users can't have a roster."); } + RosterPacket packet = new RosterPacket(); if (rosterStore != null && connection.isRosterVersioningSupported()) { packet.setVersion(rosterStore.getRosterVersion()); @@ -235,18 +240,19 @@ public class Roster { * after a logout/login. This is due to the way that XMPP stores group information. * * @param name the name of the group. - * @return a new group. - * @throws IllegalStateException if connection is not logged in or logged in anonymously + * @return a new group, or null if the group already exists + * @throws NotLoggedInException If not logged in. + * @throws IllegalStateException if logged in anonymously */ - public RosterGroup createGroup(String name) { + public RosterGroup createGroup(String name) throws NotLoggedInException { if (!connection.isAuthenticated()) { - throw new IllegalStateException("Not logged in to server."); + throw new NotLoggedInException(); } if (connection.isAnonymous()) { throw new IllegalStateException("Anonymous users can't have a roster."); } if (groups.containsKey(name)) { - throw new IllegalArgumentException("Group with name " + name + " alread exists."); + return null; } RosterGroup group = new RosterGroup(name, connection); @@ -262,12 +268,15 @@ public class Roster { * @param name the nickname of the user. * @param groups the list of group names the entry will belong to, or null if the * the roster entry won't belong to a group. - * @throws XMPPException if an XMPP exception occurs. - * @throws IllegalStateException if connection is not logged in or logged in anonymously + * @throws NotLoggedInException + * @throws NoResponseException if there was no response from the server. + * @throws XMPPErrorException if an XMPP exception occurs. + * @throws NotLoggedInException If not logged in. + * @throws IllegalStateException if logged in anonymously */ - public void createEntry(String user, String name, String[] groups) throws XMPPException { + public void createEntry(String user, String name, String[] groups) throws NotLoggedInException, NoResponseException, XMPPErrorException { if (!connection.isAuthenticated()) { - throw new IllegalStateException("Not logged in to server."); + throw new NotLoggedInException(); } if (connection.isAnonymous()) { throw new IllegalStateException("Anonymous users can't have a roster."); @@ -300,12 +309,14 @@ public class Roster { * to send an updated subscription status. * * @param entry a roster entry. - * @throws XMPPException if an XMPP error occurs. + * @throws XMPPErrorException if an XMPP error occurs. + * @throws NotLoggedInException if not logged in. + * @throws NoResponseException SmackException if there was no response from the server. * @throws IllegalStateException if connection is not logged in or logged in anonymously */ - public void removeEntry(RosterEntry entry) throws XMPPException { + public void removeEntry(RosterEntry entry) throws NotLoggedInException, NoResponseException, XMPPErrorException { if (!connection.isAuthenticated()) { - throw new IllegalStateException("Not logged in to server."); + throw new NotLoggedInException(); } if (connection.isAnonymous()) { throw new IllegalStateException("Anonymous users can't have a roster."); @@ -654,7 +665,7 @@ public class Roster { private void addUpdateEntry(Collection addedEntries, Collection updatedEntries, RosterPacket.Item item, - RosterEntry entry) { + RosterEntry entry) throws SmackException { RosterEntry oldEntry = entries.put(item.getUser(), entry); if (oldEntry == null) { addedEntries.add(item.getUser()); @@ -922,10 +933,14 @@ public class Roster { Collection updatedEntries = new ArrayList(); Collection deletedEntries = new ArrayList(); - if (packet instanceof RosterPacket) { - nonemptyResult((RosterPacket) packet, addedEntries, updatedEntries, deletedEntries); - } else { - emptyResult(addedEntries, updatedEntries); + try { + if (packet instanceof RosterPacket) { + nonemptyResult((RosterPacket) packet, addedEntries, updatedEntries, deletedEntries); + } else { + emptyResult(addedEntries, updatedEntries); + } + } catch (SmackException e) { + return; } synchronized (Roster.this) { @@ -936,7 +951,7 @@ public class Roster { fireRosterChangedEvent(addedEntries, updatedEntries, deletedEntries); } - private void emptyResult(Collection addedEntries, Collection updatedEntries) { + private void emptyResult(Collection addedEntries, Collection updatedEntries) throws SmackException { for(RosterPacket.Item item : rosterStore.getEntries()){ RosterEntry entry = new RosterEntry(item.getUser(), item.getName(), item.getItemType(), item.getItemStatus(), Roster.this, connection); @@ -945,7 +960,7 @@ public class Roster { } private void addEntries(Collection addedEntries, Collection updatedEntries, - Collection deletedEntries, String version, Collection items) { + Collection deletedEntries, String version, Collection items) throws SmackException { for (RosterPacket.Item item : items) { RosterEntry entry = new RosterEntry(item.getUser(), item.getName(), item.getItemType(), item.getItemStatus(), Roster.this, connection); @@ -968,7 +983,9 @@ public class Roster { } } - private void nonemptyResult(RosterPacket packet, Collection addedEntries, Collection updatedEntries, Collection deletedEntries) { + private void nonemptyResult(RosterPacket packet, Collection addedEntries, + Collection updatedEntries, Collection deletedEntries) + throws SmackException { RosterPacket rosterPacket = (RosterPacket) packet; String version = rosterPacket.getVersion(); @@ -1021,7 +1038,12 @@ public class Roster { Collection deletedEntries = new ArrayList(); Item item = items.iterator().next(); - processPushItem(addedEntries, updatedEntries, deletedEntries, version, item); + try { + processPushItem(addedEntries, updatedEntries, deletedEntries, version, item); + } + catch (SmackException e) { + return; + } connection.sendPacket(IQ.createResultIQ(rosterPacket)); @@ -1032,7 +1054,7 @@ public class Roster { } private void processPushItem(Collection addedEntries, Collection updatedEntries, - Collection deletedEntries, String version, Item item) { + Collection deletedEntries, String version, Item item) throws SmackException { RosterEntry entry = new RosterEntry(item.getUser(), item.getName(), item.getItemType(), item.getItemStatus(), Roster.this, connection); diff --git a/core/src/main/java/org/jivesoftware/smack/RosterGroup.java b/core/src/main/java/org/jivesoftware/smack/RosterGroup.java index da9242cc6..b56e3e286 100644 --- a/core/src/main/java/org/jivesoftware/smack/RosterGroup.java +++ b/core/src/main/java/org/jivesoftware/smack/RosterGroup.java @@ -23,6 +23,8 @@ import java.util.Collections; import java.util.LinkedHashSet; import java.util.Set; +import org.jivesoftware.smack.SmackException.NoResponseException; +import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.RosterPacket; import org.jivesoftware.smack.util.StringUtils; @@ -158,9 +160,10 @@ public class RosterGroup { * to receive the updated roster. * * @param entry a roster entry. - * @throws XMPPException if an error occured while trying to add the entry to the group. + * @throws XMPPErrorException if an error occured while trying to add the entry to the group. + * @throws NoResponseException if there was no response from the server. */ - public void addEntry(RosterEntry entry) throws XMPPException { + public void addEntry(RosterEntry entry) throws NoResponseException, XMPPErrorException { PacketCollector collector = null; // Only add the entry if it isn't already in the list. synchronized (entries) { @@ -187,9 +190,10 @@ public class RosterGroup { * to receive the updated roster. * * @param entry a roster entry. - * @throws XMPPException if an error occurred while trying to remove the entry from the group. + * @throws XMPPErrorException if an error occurred while trying to remove the entry from the group. + * @throws NoResponseException if there was no response from the server. */ - public void removeEntry(RosterEntry entry) throws XMPPException { + public void removeEntry(RosterEntry entry) throws NoResponseException, XMPPErrorException { PacketCollector collector = null; // Only remove the entry if it's in the entry list. // Remove the entry locally, if we wait for RosterPacketListenerprocess>>Packet(Packet) diff --git a/core/src/main/java/org/jivesoftware/smack/SASLAuthentication.java b/core/src/main/java/org/jivesoftware/smack/SASLAuthentication.java index afa14cb11..8323d97cb 100644 --- a/core/src/main/java/org/jivesoftware/smack/SASLAuthentication.java +++ b/core/src/main/java/org/jivesoftware/smack/SASLAuthentication.java @@ -17,12 +17,17 @@ package org.jivesoftware.smack; +import org.jivesoftware.smack.SmackException.NoResponseException; +import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.packet.Bind; import org.jivesoftware.smack.packet.Packet; import org.jivesoftware.smack.packet.Session; import org.jivesoftware.smack.sasl.*; +import org.jivesoftware.smack.sasl.SASLMechanism.SASLFailure; import javax.security.auth.callback.CallbackHandler; +import javax.security.sasl.SaslException; + import java.io.IOException; import java.lang.reflect.Constructor; import java.util.*; @@ -68,17 +73,13 @@ public class SASLAuthentication { * Boolean indicating if SASL negotiation has finished and was successful. */ private boolean saslNegotiated; - /** - * Boolean indication if SASL authentication has failed. When failed the server may end - * the connection. - */ - private boolean saslFailed; + private boolean resourceBinded; private boolean sessionSupported; /** * The SASL related error condition if there was one provided by the server. */ - private String errorCondition; + private SASLFailure saslFailure; static { @@ -205,15 +206,18 @@ public class SASLAuthentication { * @param resource the desired resource. * @param cbh the CallbackHandler used to get information from the user * @return the full JID provided by the server while binding a resource to the connection. - * @throws XMPPException if an error occures while authenticating. + * @throws IOException + * @throws XMPPErrorException + * @throws NoResponseException + * @throws SASLErrorException */ - public String authenticate(String resource, CallbackHandler cbh) - throws XMPPException { + public String authenticate(String resource, CallbackHandler cbh) throws IOException, + NoResponseException, XMPPErrorException, SASLErrorException { // Locate the SASLMechanism to use String selectedMechanism = null; for (String mechanism : mechanismsPreferences) { - if (implementedMechanisms.containsKey(mechanism) && - serverMechanisms.contains(mechanism)) { + if (implementedMechanisms.containsKey(mechanism) + && serverMechanisms.contains(mechanism)) { selectedMechanism = mechanism; break; } @@ -221,58 +225,55 @@ public class SASLAuthentication { if (selectedMechanism != null) { // A SASL mechanism was found. Authenticate using the selected mechanism and then // proceed to bind a resource + Class mechanismClass = implementedMechanisms.get(selectedMechanism); + + Constructor constructor; try { - Class mechanismClass = implementedMechanisms.get(selectedMechanism); - Constructor constructor = mechanismClass.getConstructor(SASLAuthentication.class); + constructor = mechanismClass.getConstructor(SASLAuthentication.class); currentMechanism = constructor.newInstance(this); - // Trigger SASL authentication with the selected mechanism. We use - // connection.getHost() since GSAPI requires the FQDN of the server, which - // may not match the XMPP domain. - currentMechanism.authenticate(connection.getHost(), cbh); - - // Wait until SASL negotiation finishes - synchronized (this) { - if (!saslNegotiated && !saslFailed) { - try { - wait(30000); - } - catch (InterruptedException e) { - // Ignore - } - } - } - - if (saslFailed) { - // SASL authentication failed and the server may have closed the connection - // so throw an exception - if (errorCondition != null) { - throw new XMPPException("SASL authentication " + - selectedMechanism + " failed: " + errorCondition); - } - else { - throw new XMPPException("SASL authentication failed using mechanism " + - selectedMechanism); - } - } - - if (saslNegotiated) { - // Bind a resource for this connection and - return bindResourceAndEstablishSession(resource); - } else { - // SASL authentication failed - } - } - catch (XMPPException e) { - throw e; } catch (Exception e) { - e.printStackTrace(); + throw new SaslException("Exception when creating the SASLAuthentication instance", + e); } + + // Trigger SASL authentication with the selected mechanism. We use + // connection.getHost() since GSAPI requires the FQDN of the server, which + // may not match the XMPP domain. + currentMechanism.authenticate(connection.getHost(), cbh); + + // Wait until SASL negotiation finishes + synchronized (this) { + if (!saslNegotiated && saslFailure == null) { + try { + wait(30000); + } + catch (InterruptedException e) { + // Ignore + } + } + } + + if (saslFailure != null) { + // SASL authentication failed and the server may have closed the connection + // so throw an exception + throw new SASLErrorException(selectedMechanism, saslFailure); + } + + if (saslNegotiated) { + // Bind a resource for this connection and + return bindResourceAndEstablishSession(resource); + } + else { + // SASL authentication failed + throw new SaslException(); + } + } else { - throw new XMPPException("SASL Authentication failed. No known authentication mechanisims."); + throw new SaslException( + "SASL Authentication failed. No known authentication mechanisims."); } - throw new XMPPException("SASL authentication failed"); } /** @@ -287,15 +288,20 @@ public class SASLAuthentication { * @param password the password to send to the server. * @param resource the desired resource. * @return the full JID provided by the server while binding a resource to the connection. - * @throws XMPPException if an error occures while authenticating. + * @throws XMPPErrorException + * @throws SASLErrorException + * @throws IOException + * @throws SaslException + * @throws SmackException */ public String authenticate(String username, String password, String resource) - throws XMPPException { + throws XMPPErrorException, SASLErrorException, SaslException, IOException, + SmackException { // Locate the SASLMechanism to use String selectedMechanism = null; for (String mechanism : mechanismsPreferences) { - if (implementedMechanisms.containsKey(mechanism) && - serverMechanisms.contains(mechanism)) { + if (implementedMechanisms.containsKey(mechanism) + && serverMechanisms.contains(mechanism)) { selectedMechanism = mechanism; break; } @@ -303,65 +309,56 @@ public class SASLAuthentication { if (selectedMechanism != null) { // A SASL mechanism was found. Authenticate using the selected mechanism and then // proceed to bind a resource + Class mechanismClass = implementedMechanisms.get(selectedMechanism); try { - Class mechanismClass = implementedMechanisms.get(selectedMechanism); Constructor constructor = mechanismClass.getConstructor(SASLAuthentication.class); currentMechanism = constructor.newInstance(this); - // Trigger SASL authentication with the selected mechanism. We use - // connection.getHost() since GSAPI requires the FQDN of the server, which - // may not match the XMPP domain. - - //The serviceName is basically the value that XMPP server sends to the client as being the location - //of the XMPP service we are trying to connect to. This should have the format: host [ "/" serv-name ] - //as per RFC-2831 guidelines - String serviceName = connection.getServiceName(); - currentMechanism.authenticate(username, connection.getHost(), serviceName, password); - - // Wait until SASL negotiation finishes - synchronized (this) { - if (!saslNegotiated && !saslFailed) { - try { - wait(30000); - } - catch (InterruptedException e) { - // Ignore - } - } - } - - if (saslFailed) { - // SASL authentication failed and the server may have closed the connection - // so throw an exception - if (errorCondition != null) { - throw new XMPPException("SASL authentication " + - selectedMechanism + " failed: " + errorCondition); - } - else { - throw new XMPPException("SASL authentication failed using mechanism " + - selectedMechanism); - } - } - - if (saslNegotiated) { - // Bind a resource for this connection and - return bindResourceAndEstablishSession(resource); - } - else { - // SASL authentication failed - throw new XMPPException("SASL authentication failed"); - } - } - catch (XMPPException e) { - throw e; } catch (Exception e) { + throw new SaslException("Exception when creating the SASLAuthentication instance", + e); + } + + // Trigger SASL authentication with the selected mechanism. We use + // connection.getHost() since GSAPI requires the FQDN of the server, which + // may not match the XMPP domain. + + // The serviceName is basically the value that XMPP server sends to the client as being + // the location of the XMPP service we are trying to connect to. This should have the + // format: host ["/" serv-name ] as per RFC-2831 guidelines + String serviceName = connection.getServiceName(); + currentMechanism.authenticate(username, connection.getHost(), serviceName, password); + + // Wait until SASL negotiation finishes + synchronized (this) { + if (!saslNegotiated && saslFailure == null) { + try { + wait(30000); + } + catch (InterruptedException e) { + // Ignore + } + } + } + + if (saslFailure != null) { + // SASL authentication failed and the server may have closed the connection + // so throw an exception + throw new SASLErrorException(selectedMechanism, saslFailure); + } + + if (saslNegotiated) { + // Bind a resource for this connection and + return bindResourceAndEstablishSession(resource); + } + else { // SASL authentication failed - throw new XMPPException("SASL authentication failed", e); + throw new SaslException(); } } else { - // No SASL method was found, throw an exception - throw new XMPPException("SASL authentication not supported by server"); + throw new SaslException( + "SASL Authentication failed. No known authentication mechanisims."); } } @@ -374,16 +371,19 @@ public class SASLAuthentication { * no username. * * @return the full JID provided by the server while binding a resource to the connection. - * @throws XMPPException if an error occures while authenticating. + * @throws SASLErrorException + * @throws IOException + * @throws SaslException + * @throws XMPPErrorException if an error occures while authenticating. + * @throws SmackException if there was no response from the server. */ - public String authenticateAnonymously() throws XMPPException { - try { + public String authenticateAnonymously() throws SASLErrorException, SaslException, IOException, SmackException, XMPPErrorException { currentMechanism = new SASLAnonymous(this); currentMechanism.authenticate(null,null,null,""); // Wait until SASL negotiation finishes synchronized (this) { - if (!saslNegotiated && !saslFailed) { + if (!saslNegotiated && saslFailure == null) { try { wait(5000); } @@ -393,15 +393,10 @@ public class SASLAuthentication { } } - if (saslFailed) { + if (saslFailure != null) { // SASL authentication failed and the server may have closed the connection // so throw an exception - if (errorCondition != null) { - throw new XMPPException("SASL authentication failed: " + errorCondition); - } - else { - throw new XMPPException("SASL authentication failed"); - } + throw new SASLErrorException(currentMechanism.toString(), saslFailure); } if (saslNegotiated) { @@ -409,14 +404,11 @@ public class SASLAuthentication { return bindResourceAndEstablishSession(null); } else { - throw new XMPPException("SASL authentication failed"); + throw new SaslException(); } - } catch (IOException e) { - throw new XMPPException("IOException while anonymous SASL authentication", e); - } } - private String bindResourceAndEstablishSession(String resource) throws XMPPException { + private String bindResourceAndEstablishSession(String resource) throws NoResponseException, XMPPErrorException { // Wait until server sends response containing the element synchronized (this) { if (!resourceBinded) { @@ -430,8 +422,9 @@ public class SASLAuthentication { } if (!resourceBinded) { - // Server never offered resource binding - throw new XMPPException("Resource binding not offered by server"); + // Server never offered resource binding, which is REQURIED in XMPP client and server + // implementations as per RFC6120 7.2 + throw new IllegalStateException("Resource binding not offered by server"); } Bind bindResource = new Bind(); @@ -497,12 +490,12 @@ public class SASLAuthentication { * Notification message saying that SASL authentication has failed. The server may have * closed the connection depending on the number of possible retries. * - * @param condition the error condition provided by the server. + * @param saslFailure the SASL failure as reported by the server + * @see RFC6120 6.5 */ - void authenticationFailed(String condition) { + void authenticationFailed(SASLFailure saslFailure) { synchronized (this) { - saslFailed = true; - errorCondition = condition; + this.saslFailure = saslFailure; // Wake up the thread that is waiting in the #authenticate method notify(); } @@ -540,7 +533,7 @@ public class SASLAuthentication { */ protected void init() { saslNegotiated = false; - saslFailed = false; + saslFailure = null; resourceBinded = false; sessionSupported = false; } diff --git a/core/src/main/java/org/jivesoftware/smack/SmackError.java b/core/src/main/java/org/jivesoftware/smack/SmackError.java deleted file mode 100644 index 95a3871fb..000000000 --- a/core/src/main/java/org/jivesoftware/smack/SmackError.java +++ /dev/null @@ -1,40 +0,0 @@ -/** - * - * Copyright the original author or authors - * - * 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.smack; - -public enum SmackError { - NO_RESPONSE_FROM_SERVER("No response from server."); - - private String message; - - private SmackError(String errMessage) { - message = errMessage; - } - - public String getErrorMessage() { - return message; - } - - public static SmackError getErrorCode(String message) { - for (SmackError code : values()) { - if (code.message.equals(message)) { - return code; - } - } - return null; - } -} diff --git a/core/src/main/java/org/jivesoftware/smack/SmackException.java b/core/src/main/java/org/jivesoftware/smack/SmackException.java new file mode 100644 index 000000000..7e8131be0 --- /dev/null +++ b/core/src/main/java/org/jivesoftware/smack/SmackException.java @@ -0,0 +1,159 @@ +/** + * + * Copyright 2014 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.smack; + +import java.util.ArrayList; +import java.util.List; + +import org.jivesoftware.smack.util.dns.HostAddress; + +/** + * Smack uses SmackExceptions for errors that are not defined by any XMPP specification. + * + * @author Florian Schmaus + */ +public class SmackException extends Exception { + + /** + * + */ + private static final long serialVersionUID = 1844674365368214457L; + + /** + * Creates a new SmackException with the Throwable that was the root cause of the exception. + * + * @param wrappedThrowable the root cause of the exception. + */ + public SmackException(Throwable wrappedThrowable) { + super(wrappedThrowable); + } + + public SmackException(String message) { + super(message); + } + + public SmackException(String message, Throwable wrappedThrowable) { + super(message, wrappedThrowable); + } + + protected SmackException() { + } + + /** + * Exception thrown always when there was no response to an IQ request within the packet reply + * timeout of the used connection instance. + */ + public static class NoResponseException extends SmackException { + /** + * + */ + private static final long serialVersionUID = -6523363748984543636L; + + public NoResponseException() { + } + } + + public static class NotLoggedInException extends SmackException { + + /** + * + */ + private static final long serialVersionUID = 3216216839100019278L; + + public NotLoggedInException() { + } + } + + public static class AlreadyLoggedInException extends SmackException { + + /** + * + */ + private static final long serialVersionUID = 5011416918049935231L; + + public AlreadyLoggedInException() { + } + } + + public static class NotConnectedException extends SmackException { + + /** + * + */ + private static final long serialVersionUID = 9197980400776001173L; + + public NotConnectedException() { + } + } + + public static class IllegalStateChangeException extends SmackException { + + /** + * + */ + private static final long serialVersionUID = -1766023961577168927L; + + public IllegalStateChangeException() { + } + } + + public static class SecurityRequiredException extends SmackException { + + /** + * + */ + private static final long serialVersionUID = 384291845029773545L; + + public SecurityRequiredException() { + } + } + + public static class ConnectionException extends SmackException { + + /** + * + */ + private static final long serialVersionUID = 1686944201672697996L; + + private final List failedAddresses; + + public ConnectionException(Throwable wrappedThrowable) { + super(wrappedThrowable); + failedAddresses = new ArrayList(0); + } + + public ConnectionException(List failedAddresses) { + this.failedAddresses = failedAddresses; + } + + public List getFailedAddresses() { + return failedAddresses; + } + } + + public static class FeatureNotSupportedException extends SmackException { + + /** + * + */ + private static final long serialVersionUID = 4713404802621452016L; + + public FeatureNotSupportedException(String message) { + super(message); + } + } +} diff --git a/core/src/main/java/org/jivesoftware/smack/XMPPConnection.java b/core/src/main/java/org/jivesoftware/smack/XMPPConnection.java index eb8190a0e..29701edaf 100644 --- a/core/src/main/java/org/jivesoftware/smack/XMPPConnection.java +++ b/core/src/main/java/org/jivesoftware/smack/XMPPConnection.java @@ -16,6 +16,7 @@ */ package org.jivesoftware.smack; +import java.io.IOException; import java.io.Reader; import java.io.Writer; import java.lang.reflect.Constructor; @@ -38,6 +39,9 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.logging.Level; import java.util.logging.Logger; +import javax.security.sasl.SaslException; + +import org.jivesoftware.smack.SmackException.ConnectionException; import org.jivesoftware.smack.compression.XMPPInputOutputStream; import org.jivesoftware.smack.debugger.SmackDebugger; import org.jivesoftware.smack.filter.IQReplyFilter; @@ -357,9 +361,12 @@ public abstract class XMPPConnection { * Listeners will be preserved from a previous connection if the reconnection * occurs after an abrupt termination. * - * @throws XMPPException if an error occurs while trying to establish the connection. + * @throws XMPPException if an error occurs on the XMPP protocol level. + * @throws SmackException if an error occurs somehwere else besides XMPP protocol level. + * @throws IOException + * @throws ConnectionException with detailed information about the failed connection. */ - public abstract void connect() throws XMPPException; + public abstract void connect() throws SmackException, IOException, XMPPException; /** * Logs in to the server using the strongest authentication mode supported by @@ -382,9 +389,12 @@ public abstract class XMPPConnection { * * @param username the username. * @param password the password or null if using a CallbackHandler. - * @throws XMPPException if an error occurs. + * @throws XMPPException if an error occurs on the XMPP protocol level. + * @throws SmackException if an error occurs somehwere else besides XMPP protocol level. + * @throws IOException + * @throws SaslException */ - public void login(String username, String password) throws XMPPException { + public void login(String username, String password) throws XMPPException, SmackException, SaslException, IOException { login(username, password, "Smack"); } @@ -410,11 +420,12 @@ public abstract class XMPPConnection { * @param username the username. * @param password the password or null if using a CallbackHandler. * @param resource the resource. - * @throws XMPPException if an error occurs. - * @throws IllegalStateException if not connected to the server, or already logged in - * to the serrver. + * @throws XMPPException if an error occurs on the XMPP protocol level. + * @throws SmackException if an error occurs somehwere else besides XMPP protocol level. + * @throws IOException + * @throws SaslException */ - public abstract void login(String username, String password, String resource) throws XMPPException; + public abstract void login(String username, String password, String resource) throws XMPPException, SmackException, SaslException, IOException; /** * Logs in to the server anonymously. Very few servers are configured to support anonymous @@ -422,11 +433,12 @@ public abstract class XMPPConnection { * does succeed, your XMPP address will likely be in the form "123ABC@server/789XYZ" or * "server/123ABC" (where "123ABC" and "789XYZ" is a random value generated by the server). * - * @throws XMPPException if an error occurs or anonymous logins are not supported by the server. - * @throws IllegalStateException if not connected to the server, or already logged in - * to the serrver. + * @throws XMPPException if an error occurs on the XMPP protocol level. + * @throws SmackException if an error occurs somehwere else besides XMPP protocol level. + * @throws IOException + * @throws SaslException */ - public abstract void loginAnonymously() throws XMPPException; + public abstract void loginAnonymously() throws XMPPException, SmackException, SaslException, IOException; /** * Sends the specified packet to the server. @@ -470,8 +482,10 @@ public abstract class XMPPConnection { * {@link RosterListener}s will throw an IllegalStateException. * * @return the user's roster. + * @throws XMPPException if an error occurs on the XMPP protocol level. + * @throws SmackException if an error occurs somehwere else besides XMPP protocol level. */ - public abstract Roster getRoster(); + public abstract Roster getRoster() throws XMPPException, SmackException; /** * Returns the SASLAuthentication manager that is responsible for authenticating with diff --git a/core/src/main/java/org/jivesoftware/smack/XMPPException.java b/core/src/main/java/org/jivesoftware/smack/XMPPException.java index 87e675f65..694a0cb00 100644 --- a/core/src/main/java/org/jivesoftware/smack/XMPPException.java +++ b/core/src/main/java/org/jivesoftware/smack/XMPPException.java @@ -26,7 +26,7 @@ import org.jivesoftware.smack.packet.XMPPError; * and textual description of the problem, which are encapsulated in the XMPPError * class. When appropriate, an XMPPError instance is attached instances of this exception.

* - * When a stream error occured, the server will send a stream error to the client before + * When a stream error occurred, the server will send a stream error to the client before * closing the connection. Stream errors are unrecoverable errors. When a stream error * is sent to the client an XMPPException will be thrown containing the StreamError sent * by the server. @@ -34,17 +34,14 @@ import org.jivesoftware.smack.packet.XMPPError; * @see XMPPError * @author Matt Tucker */ -public class XMPPException extends Exception { +public abstract class XMPPException extends Exception { private static final long serialVersionUID = 6881651633890968625L; - private StreamError streamError = null; - private XMPPError error = null; - private SmackError smackError = null; /** * Creates a new XMPPException. */ - public XMPPException() { + protected XMPPException() { super(); } @@ -53,52 +50,10 @@ public class XMPPException extends Exception { * * @param message description of the exception. */ - public XMPPException(String message) { + protected XMPPException(String message) { super(message); } - /** - * Creates a new XMPPException with a Smack specific error code. - * - * @param code the root cause of the exception. - */ - public XMPPException(SmackError code) { - super(code.getErrorMessage()); - smackError = code; - } - - /** - * Creates a new XMPPException with the Throwable that was the root cause of the - * exception. - * - * @param wrappedThrowable the root cause of the exception. - */ - public XMPPException(Throwable wrappedThrowable) { - super(wrappedThrowable); - } - - /** - * Creates a new XMPPException with the stream error that was the root case of the - * exception. When a stream error is received from the server then the underlying - * TCP connection will be closed by the server. - * - * @param streamError the root cause of the exception. - */ - public XMPPException(StreamError streamError) { - super(); - this.streamError = streamError; - } - - /** - * Cretaes a new XMPPException with the XMPPError that was the root case of the - * exception. - * - * @param error the root cause of the exception. - */ - public XMPPException(XMPPError error) { - super(); - this.error = error; - } /** * Creates a new XMPPException with a description of the exception and the @@ -107,95 +62,116 @@ public class XMPPException extends Exception { * @param message a description of the exception. * @param wrappedThrowable the root cause of the exception. */ - public XMPPException(String message, Throwable wrappedThrowable) { + protected XMPPException(String message, Throwable wrappedThrowable) { super(message, wrappedThrowable); } - /** - * Creates a new XMPPException with a description of the exception, an XMPPError, - * and the Throwable that was the root cause of the exception. - * - * @param message a description of the exception. - * @param error the root cause of the exception. - * @param wrappedThrowable the root cause of the exception. - */ - public XMPPException(String message, XMPPError error, Throwable wrappedThrowable) { - super(message, wrappedThrowable); - this.error = error; - } + public static class XMPPErrorException extends XMPPException { + /** + * + */ + private static final long serialVersionUID = 212790389529249604L; + private final XMPPError error; - /** - * Creates a new XMPPException with a description of the exception and the - * XMPPException that was the root cause of the exception. - * - * @param message a description of the exception. - * @param error the root cause of the exception. - */ - public XMPPException(String message, XMPPError error) { - super(message); - this.error = error; - } - - /** - * Returns the XMPPError asscociated with this exception, or null if there - * isn't one. - * - * @return the XMPPError asscociated with this exception. - */ - public XMPPError getXMPPError() { - return error; - } - - /** - * Returns the SmackError asscociated with this exception, or null if there - * isn't one. - * - * @return the SmackError asscociated with this exception. - */ - public SmackError getSmackError() { - return smackError; - } - - /** - * Returns the StreamError asscociated with this exception, or null if there - * isn't one. The underlying TCP connection is closed by the server after sending the - * stream error to the client. - * - * @return the StreamError asscociated with this exception. - */ - public StreamError getStreamError() { - return streamError; - } - - public String getMessage() { - String msg = super.getMessage(); - // If the message was not set, but there is an XMPPError, return the - // XMPPError as the message. - if (msg == null && error != null) { - return error.toString(); + /** + * Creates a new XMPPException with the XMPPError that was the root case of the exception. + * + * @param error the root cause of the exception. + */ + public XMPPErrorException(XMPPError error) { + super(); + this.error = error; } - else if (msg == null && streamError != null) { + + /** + * Creates a new XMPPException with a description of the exception, an XMPPError, and the + * Throwable that was the root cause of the exception. + * + * @param message a description of the exception. + * @param error the root cause of the exception. + * @param wrappedThrowable the root cause of the exception. + */ + public XMPPErrorException(String message, XMPPError error, Throwable wrappedThrowable) { + super(message, wrappedThrowable); + this.error = error; + } + + /** + * Creates a new XMPPException with a description of the exception and the XMPPException + * that was the root cause of the exception. + * + * @param message a description of the exception. + * @param error the root cause of the exception. + */ + public XMPPErrorException(String message, XMPPError error) { + super(message); + this.error = error; + } + + /** + * Returns the XMPPError associated with this exception, or null if there isn't + * one. + * + * @return the XMPPError associated with this exception. + */ + public XMPPError getXMPPError() { + return error; + } + + @Override + public String getMessage() { + String superMessage = super.getMessage(); + if (superMessage != null) { + return superMessage; + } + else { + return error.toString(); + } + } + + @Override + public String toString() { + return getMessage(); + } + } + + public static class StreamErrorException extends XMPPException { + /** + * + */ + private static final long serialVersionUID = 3400556867134848886L; + private final StreamError streamError; + + /** + * Creates a new XMPPException with the stream error that was the root case of the + * exception. When a stream error is received from the server then the underlying connection + * will be closed by the server. + * + * @param streamError the root cause of the exception. + */ + public StreamErrorException(StreamError streamError) { + super(); + this.streamError = streamError; + } + + /** + * Returns the StreamError associated with this exception. The underlying TCP connection is + * closed by the server after sending the stream error to the client. + * + * @return the StreamError associated with this exception. + */ + public StreamError getStreamError() { + return streamError; + } + + @Override + public String getMessage() { return streamError.toString(); } - return msg; - } - public String toString() { - StringBuilder buf = new StringBuilder(); - String message = super.getMessage(); - if (message != null) { - buf.append(message).append(": "); + @Override + public String toString() { + return getMessage(); } - if (error != null) { - buf.append(error); - } - if (streamError != null) { - buf.append(streamError); - } - if (getCause() != null) { - buf.append("\n -- caused by: ").append(getCause()); - } - - return buf.toString(); } } diff --git a/core/src/main/java/org/jivesoftware/smack/packet/XMPPError.java b/core/src/main/java/org/jivesoftware/smack/packet/XMPPError.java index 8137860b6..02a6fdb64 100644 --- a/core/src/main/java/org/jivesoftware/smack/packet/XMPPError.java +++ b/core/src/main/java/org/jivesoftware/smack/packet/XMPPError.java @@ -292,15 +292,26 @@ public class XMPPError { public static final Condition unexpected_request = new Condition("unexpected-request"); public static final Condition request_timeout = new Condition("request-timeout"); - private String value; + private final String value; public Condition(String value) { this.value = value; } + @Override public String toString() { return value; } + + @Override + public boolean equals(Object other) { + return toString().equals(other.toString()); + } + + @Override + public int hashCode() { + return value.hashCode(); + } } diff --git a/core/src/main/java/org/jivesoftware/smack/sasl/SASLError.java b/core/src/main/java/org/jivesoftware/smack/sasl/SASLError.java new file mode 100644 index 000000000..94cfa7f4e --- /dev/null +++ b/core/src/main/java/org/jivesoftware/smack/sasl/SASLError.java @@ -0,0 +1,45 @@ +/** + * + * Copyright 2014 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.smack.sasl; + +public enum SASLError { + + aborted, + account_disabled, + credentials_expired, + encryption_required, + incorrect_encoding, + invalid_authzid, + invalid_mechanism, + malformed_request, + not_authorized, + temporary_auth_failure; + + @Override + public String toString() { + return this.name().replace('_', '-'); + } + + public static SASLError fromString(String string) { + string = string.replace('-', '_'); + for (SASLError error : SASLError.values()) { + if (error.name().equals(string)) + return error; + } + return null; + } +} diff --git a/core/src/main/java/org/jivesoftware/smack/sasl/SASLErrorException.java b/core/src/main/java/org/jivesoftware/smack/sasl/SASLErrorException.java new file mode 100644 index 000000000..87aa3dd77 --- /dev/null +++ b/core/src/main/java/org/jivesoftware/smack/sasl/SASLErrorException.java @@ -0,0 +1,59 @@ +/** + * + * Copyright 2014 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.smack.sasl; + +import java.util.HashMap; +import java.util.Map; + +import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.sasl.SASLMechanism.SASLFailure; + +public class SASLErrorException extends XMPPException { + + /** + * + */ + private static final long serialVersionUID = 6247573875760717257L; + + private final SASLFailure saslFailure; + private final String mechanism; + private final Map texts; + + public SASLErrorException(String mechanism, SASLFailure saslFailure) { + this.mechanism = mechanism; + this.saslFailure = saslFailure; + this.texts = new HashMap(); + } + + public SASLErrorException(String mechanism, SASLFailure saslFailure, Map texts) { + this.mechanism = mechanism; + this.saslFailure = saslFailure; + this.texts = texts; + } + + public SASLFailure getSASLFailure() { + return saslFailure; + } + + public String getMechanism() { + return mechanism; + } + + public Map getTexts() { + return texts; + } +} diff --git a/core/src/main/java/org/jivesoftware/smack/sasl/SASLGSSAPIMechanism.java b/core/src/main/java/org/jivesoftware/smack/sasl/SASLGSSAPIMechanism.java index 658b14b6d..1b7728dec 100644 --- a/core/src/main/java/org/jivesoftware/smack/sasl/SASLGSSAPIMechanism.java +++ b/core/src/main/java/org/jivesoftware/smack/sasl/SASLGSSAPIMechanism.java @@ -17,12 +17,13 @@ package org.jivesoftware.smack.sasl; import org.jivesoftware.smack.SASLAuthentication; -import org.jivesoftware.smack.XMPPException; import java.io.IOException; import java.util.Map; import java.util.HashMap; + import javax.security.sasl.Sasl; +import javax.security.sasl.SaslException; import javax.security.auth.callback.CallbackHandler; /** @@ -55,7 +56,7 @@ public class SASLGSSAPIMechanism extends SASLMechanism { * @param cbh the CallbackHandler (not used with GSSAPI) * @throws IOException If a network error occures while authenticating. */ - public void authenticate(String username, String host, CallbackHandler cbh) throws IOException, XMPPException { + public void authenticate(String username, String host, CallbackHandler cbh) throws IOException, SaslException { String[] mechanisms = { getName() }; Map props = new HashMap(); props.put(Sasl.SERVER_AUTH,"TRUE"); @@ -74,7 +75,7 @@ public class SASLGSSAPIMechanism extends SASLMechanism { * @param password the password of the user (ignored for GSSAPI) * @throws IOException If a network error occures while authenticating. */ - public void authenticate(String username, String host, String password) throws IOException, XMPPException { + public void authenticate(String username, String host, String password) throws IOException, SaslException { String[] mechanisms = { getName() }; Map props = new HashMap(); props.put(Sasl.SERVER_AUTH,"TRUE"); diff --git a/core/src/main/java/org/jivesoftware/smack/sasl/SASLMechanism.java b/core/src/main/java/org/jivesoftware/smack/sasl/SASLMechanism.java index 4f5e7176d..d9abec4bf 100644 --- a/core/src/main/java/org/jivesoftware/smack/sasl/SASLMechanism.java +++ b/core/src/main/java/org/jivesoftware/smack/sasl/SASLMechanism.java @@ -16,7 +16,6 @@ */ package org.jivesoftware.smack.sasl; -import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.SASLAuthentication; import org.jivesoftware.smack.packet.Packet; import org.jivesoftware.smack.util.StringUtils; @@ -129,9 +128,9 @@ public abstract class SASLMechanism implements CallbackHandler { * serviceName format is: host [ "/" serv-name ] as per RFC-2831 * @param password the password for this account. * @throws IOException If a network error occurs while authenticating. - * @throws XMPPException If a protocol error occurs or the user is not authenticated. + * @throws SaslException */ - public void authenticate(String username, String host, String serviceName, String password) throws IOException, XMPPException { + public void authenticate(String username, String host, String serviceName, String password) throws IOException, SaslException { //Since we were not provided with a CallbackHandler, we will use our own with the given //information @@ -153,24 +152,20 @@ public abstract class SASLMechanism implements CallbackHandler { * @param host the hostname where the user account resides. * @param cbh the CallbackHandler to obtain user information. * @throws IOException If a network error occures while authenticating. - * @throws XMPPException If a protocol error occurs or the user is not authenticated. + * @throws SaslException If a protocol error occurs or the user is not authenticated. */ - public void authenticate(String host, CallbackHandler cbh) throws IOException, XMPPException { + public void authenticate(String host, CallbackHandler cbh) throws IOException, SaslException { String[] mechanisms = { getName() }; Map props = new HashMap(); sc = Sasl.createSaslClient(mechanisms, null, "xmpp", host, props, cbh); authenticate(); } - protected void authenticate() throws IOException, XMPPException { + protected void authenticate() throws IOException, SaslException { String authenticationText = null; - try { - if(sc.hasInitialResponse()) { - byte[] response = sc.evaluateChallenge(new byte[0]); - authenticationText = StringUtils.encodeBase64(response, false); - } - } catch (SaslException e) { - throw new XMPPException("SASL authentication failed", e); + if (sc.hasInitialResponse()) { + byte[] response = sc.evaluateChallenge(new byte[0]); + authenticationText = StringUtils.encodeBase64(response, false); } // Send the authentication to the server @@ -349,11 +344,19 @@ public abstract class SASLMechanism implements CallbackHandler { /** * A SASL failure stanza. */ - public static class Failure extends Packet { - final private String condition; + public static class SASLFailure extends Packet { + private final SASLError saslError; + private final String saslErrorString; - public Failure(String condition) { - this.condition = condition; + public SASLFailure(String saslError) { + SASLError error = SASLError.fromString(saslError); + if (error == null) { + // RFC6120 6.5 states that unknown condition must be treat as generic authentication failure. + this.saslError = SASLError.not_authorized; + } else { + this.saslError = error; + } + this.saslErrorString = saslError; } /** @@ -361,17 +364,22 @@ public abstract class SASLMechanism implements CallbackHandler { * * @return the SASL related error condition. */ - public String getCondition() { - return condition; + public SASLError getSASLError() { + return saslError; + } + + /** + * + * @return the SASL error as String + */ + public String getSASLErrorString() { + return saslErrorString; } public String toXML() { StringBuilder stanza = new StringBuilder(); stanza.append(""); - if (condition != null && - condition.trim().length() > 0) { - stanza.append("<").append(condition).append("/>"); - } + stanza.append("<").append(saslErrorString).append("/>"); stanza.append(""); return stanza.toString(); } diff --git a/core/src/main/java/org/jivesoftware/smack/util/PacketParserUtils.java b/core/src/main/java/org/jivesoftware/smack/util/PacketParserUtils.java index 78dee5ddc..24e91f910 100644 --- a/core/src/main/java/org/jivesoftware/smack/util/PacketParserUtils.java +++ b/core/src/main/java/org/jivesoftware/smack/util/PacketParserUtils.java @@ -42,7 +42,7 @@ import org.jivesoftware.smack.packet.XMPPError; import org.jivesoftware.smack.provider.IQProvider; import org.jivesoftware.smack.provider.PacketExtensionProvider; import org.jivesoftware.smack.provider.ProviderManager; -import org.jivesoftware.smack.sasl.SASLMechanism.Failure; +import org.jivesoftware.smack.sasl.SASLMechanism.SASLFailure; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; @@ -636,7 +636,7 @@ public class PacketParserUtils { * @return a SASL Failure packet. * @throws Exception if an exception occurs while parsing the packet. */ - public static Failure parseSASLFailure(XmlPullParser parser) throws Exception { + public static SASLFailure parseSASLFailure(XmlPullParser parser) throws Exception { String condition = null; boolean done = false; while (!done) { @@ -653,7 +653,7 @@ public class PacketParserUtils { } } } - return new Failure(condition); + return new SASLFailure(condition); } /** diff --git a/core/src/test/java/org/jivesoftware/smack/ChatConnectionTest.java b/core/src/test/java/org/jivesoftware/smack/ChatConnectionTest.java index 5fa916810..1656ae68e 100644 --- a/core/src/test/java/org/jivesoftware/smack/ChatConnectionTest.java +++ b/core/src/test/java/org/jivesoftware/smack/ChatConnectionTest.java @@ -348,7 +348,7 @@ public class ChatConnectionTest { try { con.connect(); con.login("me", "secret"); - } catch (XMPPException e) { + } catch (Exception e) { // No need for handling in a dummy connection. } return con; diff --git a/core/src/test/java/org/jivesoftware/smack/DummyConnection.java b/core/src/test/java/org/jivesoftware/smack/DummyConnection.java index faa48189c..a299733aa 100644 --- a/core/src/test/java/org/jivesoftware/smack/DummyConnection.java +++ b/core/src/test/java/org/jivesoftware/smack/DummyConnection.java @@ -74,7 +74,7 @@ public class DummyConnection extends XMPPConnection { } @Override - public void connect() throws XMPPException { + public void connect() { connectionID = "dummy-" + new Random(new Date().getTime()).nextInt(); if (reconnect) { diff --git a/core/src/test/java/org/jivesoftware/smack/RosterTest.java b/core/src/test/java/org/jivesoftware/smack/RosterTest.java index 82702ac6e..f0b9b383a 100644 --- a/core/src/test/java/org/jivesoftware/smack/RosterTest.java +++ b/core/src/test/java/org/jivesoftware/smack/RosterTest.java @@ -520,8 +520,9 @@ public class RosterTest { * * @param connection the dummy connection of which the provided roster belongs to. * @param roster the roster (or buddy list) which should be initialized. + * @throws SmackException */ - public static void initRoster(DummyConnection connection, Roster roster) throws InterruptedException, XMPPException { + public static void initRoster(DummyConnection connection, Roster roster) throws InterruptedException, XMPPException, SmackException { roster.reload(); while (true) { final Packet sentPacket = connection.getSentPacket(); diff --git a/core/src/test/java/org/jivesoftware/smack/RosterVersioningTest.java b/core/src/test/java/org/jivesoftware/smack/RosterVersioningTest.java index 814dd2648..dc31c39b2 100644 --- a/core/src/test/java/org/jivesoftware/smack/RosterVersioningTest.java +++ b/core/src/test/java/org/jivesoftware/smack/RosterVersioningTest.java @@ -83,9 +83,11 @@ public class RosterVersioningTest { /** * Tests that receiving an empty roster result causes the roster to be populated * by all entries of the roster store. + * @throws SmackException + * @throws XMPPException */ @Test(timeout = 5000) - public void testEqualVersionStored() throws InterruptedException, IOException { + public void testEqualVersionStored() throws InterruptedException, IOException, XMPPException, SmackException { connection.getRoster().reload(); answerWithEmptyRosterResult(); @@ -116,9 +118,11 @@ public class RosterVersioningTest { /** * Tests that a non-empty roster result empties the store. + * @throws SmackException + * @throws XMPPException */ @Test(timeout = 5000) - public void testOtherVersionStored() throws InterruptedException { + public void testOtherVersionStored() throws InterruptedException, XMPPException, SmackException { connection.getRoster().reload(); Item vaglafItem = vaglafItem(); diff --git a/core/src/test/java/org/jivesoftware/smack/parsing/ParsingExceptionTest.java b/core/src/test/java/org/jivesoftware/smack/parsing/ParsingExceptionTest.java index accc4292d..25a538c4b 100644 --- a/core/src/test/java/org/jivesoftware/smack/parsing/ParsingExceptionTest.java +++ b/core/src/test/java/org/jivesoftware/smack/parsing/ParsingExceptionTest.java @@ -19,7 +19,7 @@ package org.jivesoftware.smack.parsing; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; -import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.packet.PacketExtension; import org.jivesoftware.smack.provider.PacketExtensionProvider; import org.jivesoftware.smack.provider.ProviderManager; @@ -79,7 +79,7 @@ public class ParsingExceptionTest { @Override public PacketExtension parseExtension(XmlPullParser parser) throws Exception { - throw new XMPPException("Test Exception"); + throw new SmackException("Test Exception"); } } diff --git a/experimental/src/main/java/org/jivesoftware/smackx/carbons/CarbonManager.java b/experimental/src/main/java/org/jivesoftware/smackx/carbons/CarbonManager.java index 796c771b2..42c2c9735 100644 --- a/experimental/src/main/java/org/jivesoftware/smackx/carbons/CarbonManager.java +++ b/experimental/src/main/java/org/jivesoftware/smackx/carbons/CarbonManager.java @@ -20,11 +20,14 @@ import java.util.Collections; import java.util.Map; import java.util.WeakHashMap; +import org.jivesoftware.smack.SmackException; +import org.jivesoftware.smack.SmackException.NoResponseException; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.ConnectionCreationListener; import org.jivesoftware.smack.Manager; import org.jivesoftware.smack.PacketListener; import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.filter.IQReplyFilter; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.Message; @@ -95,15 +98,12 @@ public class CarbonManager extends Manager { * Returns true if XMPP Carbons are supported by the server. * * @return true if supported + * @throws SmackException if there was no response from the server. + * @throws XMPPException */ - public boolean isSupportedByServer() { - try { - return ServiceDiscoveryManager.getInstanceFor(connection()).supportsFeature( - connection().getServiceName(), CarbonExtension.NAMESPACE); - } - catch (XMPPException e) { - return false; - } + public boolean isSupportedByServer() throws XMPPException, SmackException { + return ServiceDiscoveryManager.getInstanceFor(connection()).supportsFeature( + connection().getServiceName(), CarbonExtension.NAMESPACE); } /** @@ -138,11 +138,14 @@ public class CarbonManager extends Manager { * You should first check for support using isSupportedByServer(). * * @param new_state whether carbons should be enabled or disabled + * @throws XMPPErrorException + * @throws NoResponseException * - * @throws XMPPException */ - public void setCarbonsEnabled(final boolean new_state) throws XMPPException { - if (enabled_state == new_state) return; + public synchronized void setCarbonsEnabled(final boolean new_state) throws NoResponseException, + XMPPErrorException { + if (enabled_state == new_state) + return; IQ setIQ = carbonsEnabledIQ(new_state); @@ -154,8 +157,9 @@ public class CarbonManager extends Manager { * Helper method to enable carbons. * * @throws XMPPException + * @throws SmackException if there was no response from the server. */ - public void enableCarbons() throws XMPPException { + public void enableCarbons() throws XMPPException, SmackException { setCarbonsEnabled(true); } @@ -163,8 +167,9 @@ public class CarbonManager extends Manager { * Helper method to disable carbons. * * @throws XMPPException + * @throws SmackException if there was no response from the server. */ - public void disableCarbons() throws XMPPException { + public void disableCarbons() throws XMPPException, SmackException { setCarbonsEnabled(false); } diff --git a/extensions/src/main/java/org/jivesoftware/smackx/address/MultipleRecipientManager.java b/extensions/src/main/java/org/jivesoftware/smackx/address/MultipleRecipientManager.java index d977af437..06dc2d9b0 100644 --- a/extensions/src/main/java/org/jivesoftware/smackx/address/MultipleRecipientManager.java +++ b/extensions/src/main/java/org/jivesoftware/smackx/address/MultipleRecipientManager.java @@ -17,8 +17,11 @@ package org.jivesoftware.smackx.address; +import org.jivesoftware.smack.SmackException; +import org.jivesoftware.smack.SmackException.NoResponseException; +import org.jivesoftware.smack.SmackException.FeatureNotSupportedException; import org.jivesoftware.smack.XMPPConnection; -import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.packet.Message; import org.jivesoftware.smack.packet.Packet; import org.jivesoftware.smack.util.Cache; @@ -31,8 +34,6 @@ import org.jivesoftware.smackx.disco.packet.DiscoverItems; import java.util.ArrayList; import java.util.Iterator; import java.util.List; -import java.util.logging.Level; -import java.util.logging.Logger; /** * A MultipleRecipientManager allows to send packets to multiple recipients by making use of @@ -42,7 +43,6 @@ import java.util.logging.Logger; * @author Gaston Dombiak */ public class MultipleRecipientManager { - private static final Logger LOGGER = Logger.getLogger(MultipleRecipientManager.class.getName()); /** * Create a cache to hold the 100 most recently accessed elements for a period of @@ -65,39 +65,42 @@ public class MultipleRecipientManager { * list exists. * @param bcc the list of JIDs to include in the BCC list or null if no BCC * list exists. - * @throws XMPPException if server does not support JEP-33: Extended Stanza Addressing and + * @throws FeatureNotSupportedException if special XEP-33 features where requested, but the + * server does not support them. + * @throws XMPPErrorException if server does not support JEP-33: Extended Stanza Addressing and * some JEP-33 specific features were requested. + * @throws NoResponseException if there was no response from the server. */ - public static void send(XMPPConnection connection, Packet packet, List to, List cc, List bcc) - throws XMPPException { + public static void send(XMPPConnection connection, Packet packet, List to, List cc, List bcc) throws NoResponseException, XMPPErrorException, FeatureNotSupportedException + { send(connection, packet, to, cc, bcc, null, null, false); } /** - * Sends the specified packet to the list of specified recipients using the - * specified connection. If the server has support for JEP-33 then only one - * packet is going to be sent to the server with the multiple recipient instructions. - * However, if JEP-33 is not supported by the server then the client is going to send - * the packet to each recipient. - * + * Sends the specified packet to the list of specified recipients using the specified + * connection. If the server has support for JEP-33 then only one packet is going to be sent to + * the server with the multiple recipient instructions. However, if JEP-33 is not supported by + * the server then the client is going to send the packet to each recipient. + * * @param connection the connection to use to send the packet. - * @param packet the packet to send to the list of recipients. - * @param to the list of JIDs to include in the TO list or null if no TO - * list exists. - * @param cc the list of JIDs to include in the CC list or null if no CC - * list exists. - * @param bcc the list of JIDs to include in the BCC list or null if no BCC - * list exists. - * @param replyTo address to which all replies are requested to be sent or null - * indicating that they can reply to any address. - * @param replyRoom JID of a MUC room to which responses should be sent or null - * indicating that they can reply to any address. - * @param noReply true means that receivers should not reply to the message. - * @throws XMPPException if server does not support JEP-33: Extended Stanza Addressing and - * some JEP-33 specific features were requested. + * @param packet the packet to send to the list of recipients. + * @param to the list of JIDs to include in the TO list or null if no TO list exists. + * @param cc the list of JIDs to include in the CC list or null if no CC list exists. + * @param bcc the list of JIDs to include in the BCC list or null if no BCC list + * exists. + * @param replyTo address to which all replies are requested to be sent or null + * indicating that they can reply to any address. + * @param replyRoom JID of a MUC room to which responses should be sent or null + * indicating that they can reply to any address. + * @param noReply true means that receivers should not reply to the message. + * @throws XMPPErrorException if server does not support JEP-33: Extended Stanza Addressing and + * some JEP-33 specific features were requested. + * @throws NoResponseException if there was no response from the server. + * @throws FeatureNotSupportedException if special XEP-33 features where requested, but the + * server does not support them. */ public static void send(XMPPConnection connection, Packet packet, List to, List cc, List bcc, - String replyTo, String replyRoom, boolean noReply) throws XMPPException { + String replyTo, String replyRoom, boolean noReply) throws NoResponseException, XMPPErrorException, FeatureNotSupportedException { String serviceAddress = getMultipleRecipienServiceAddress(connection); if (serviceAddress != null) { // Send packet to target users using multiple recipient service provided by the server @@ -110,7 +113,7 @@ public class MultipleRecipientManager { (replyRoom != null && replyRoom.trim().length() > 0)) { // Some specified JEP-33 features were requested so throw an exception alerting // the user that this features are not available - throw new XMPPException("Extended Stanza Addressing not supported by server"); + throw new FeatureNotSupportedException("Extended Stanza Addressing not supported by server"); } // Send the packet to each individual recipient sendToIndividualRecipients(connection, packet, to, cc, bcc); @@ -125,20 +128,20 @@ public class MultipleRecipientManager { * @param connection the connection to use to send the reply. * @param original the previously received packet that was sent to multiple recipients. * @param reply the new message to send as a reply. - * @throws XMPPException if the original message was not sent to multiple recipients, or the - * original message cannot be replied or reply should be sent to a room. + * @throws SmackException + * @throws XMPPErrorException */ - public static void reply(XMPPConnection connection, Message original, Message reply) - throws XMPPException { + public static void reply(XMPPConnection connection, Message original, Message reply) throws SmackException, XMPPErrorException + { MultipleRecipientInfo info = getMultipleRecipientInfo(original); if (info == null) { - throw new XMPPException("Original message does not contain multiple recipient info"); + throw new SmackException("Original message does not contain multiple recipient info"); } if (info.shouldNotReply()) { - throw new XMPPException("Original message should not be replied"); + throw new SmackException("Original message should not be replied"); } if (info.getReplyRoom() != null) { - throw new XMPPException("Reply should be sent through a room"); + throw new SmackException("Reply should be sent through a room"); } // Any element from the initial message MUST be copied into the reply. if (original.getThread() != null) { @@ -280,8 +283,10 @@ public class MultipleRecipientManager { * @param connection the connection to use for disco. The connected server is going to be * queried. * @return the address of the multiple recipients service or null if none was found. + * @throws NoResponseException if there was no response from the server. + * @throws XMPPErrorException */ - private static String getMultipleRecipienServiceAddress(XMPPConnection connection) { + private static String getMultipleRecipienServiceAddress(XMPPConnection connection) throws NoResponseException, XMPPErrorException { String serviceName = connection.getServiceName(); String serviceAddress = (String) services.get(serviceName); if (serviceAddress == null) { @@ -290,33 +295,28 @@ public class MultipleRecipientManager { if (serviceAddress == null) { // Send the disco packet to the server itself - try { - DiscoverInfo info = ServiceDiscoveryManager.getInstanceFor(connection) - .discoverInfo(serviceName); - // Check if the server supports JEP-33 - if (info.containsFeature("http://jabber.org/protocol/address")) { - serviceAddress = serviceName; - } - else { - // Get the disco items and send the disco packet to each server item - DiscoverItems items = ServiceDiscoveryManager.getInstanceFor(connection) - .discoverItems(serviceName); - for (Iterator it = items.getItems(); it.hasNext();) { - DiscoverItems.Item item = it.next(); - info = ServiceDiscoveryManager.getInstanceFor(connection) - .discoverInfo(item.getEntityID(), item.getNode()); - if (info.containsFeature("http://jabber.org/protocol/address")) { - serviceAddress = serviceName; - break; - } + DiscoverInfo info = ServiceDiscoveryManager.getInstanceFor(connection).discoverInfo( + serviceName); + // Check if the server supports JEP-33 + if (info.containsFeature("http://jabber.org/protocol/address")) { + serviceAddress = serviceName; + } + else { + // Get the disco items and send the disco packet to each server item + DiscoverItems items = ServiceDiscoveryManager.getInstanceFor(connection).discoverItems( + serviceName); + for (Iterator it = items.getItems(); it.hasNext();) { + DiscoverItems.Item item = it.next(); + info = ServiceDiscoveryManager.getInstanceFor(connection).discoverInfo( + item.getEntityID(), item.getNode()); + if (info.containsFeature("http://jabber.org/protocol/address")) { + serviceAddress = serviceName; + break; } } - // Cache the discovered information - services.put(serviceName, serviceAddress == null ? "" : serviceAddress); - } - catch (XMPPException e) { - LOGGER.log(Level.SEVERE, "Error occurred retrieving multiple recipients service", e); } + // Cache the discovered information + services.put(serviceName, serviceAddress == null ? "" : serviceAddress); } } } diff --git a/extensions/src/main/java/org/jivesoftware/smackx/amp/AMPDeliverCondition.java b/extensions/src/main/java/org/jivesoftware/smackx/amp/AMPDeliverCondition.java index d8e705d71..81d709fb7 100644 --- a/extensions/src/main/java/org/jivesoftware/smackx/amp/AMPDeliverCondition.java +++ b/extensions/src/main/java/org/jivesoftware/smackx/amp/AMPDeliverCondition.java @@ -16,8 +16,9 @@ */ package org.jivesoftware.smackx.amp; +import org.jivesoftware.smack.SmackException.NoResponseException; import org.jivesoftware.smack.XMPPConnection; -import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smackx.amp.packet.AMPExtension; public class AMPDeliverCondition implements AMPExtension.Condition { @@ -28,9 +29,10 @@ public class AMPDeliverCondition implements AMPExtension.Condition { * Check if server supports deliver condition * @param connection Smack connection instance * @return true if deliver condition is supported. - * @throws XMPPException + * @throws XMPPErrorException + * @throws NoResponseException */ - public static boolean isSupported(XMPPConnection connection) throws XMPPException { + public static boolean isSupported(XMPPConnection connection) throws NoResponseException, XMPPErrorException { return AMPManager.isConditionSupported(connection, NAME); } diff --git a/extensions/src/main/java/org/jivesoftware/smackx/amp/AMPExpireAtCondition.java b/extensions/src/main/java/org/jivesoftware/smackx/amp/AMPExpireAtCondition.java index 83b098038..accf93dd1 100644 --- a/extensions/src/main/java/org/jivesoftware/smackx/amp/AMPExpireAtCondition.java +++ b/extensions/src/main/java/org/jivesoftware/smackx/amp/AMPExpireAtCondition.java @@ -16,8 +16,9 @@ */ package org.jivesoftware.smackx.amp; +import org.jivesoftware.smack.SmackException.NoResponseException; import org.jivesoftware.smack.XMPPConnection; -import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.util.XmppDateTime; import org.jivesoftware.smackx.amp.packet.AMPExtension; @@ -32,9 +33,10 @@ public class AMPExpireAtCondition implements AMPExtension.Condition { * Check if server supports expire-at condition * @param connection Smack connection instance * @return true if expire-at condition is supported. - * @throws XMPPException + * @throws XMPPErrorException + * @throws NoResponseException */ - public static boolean isSupported(XMPPConnection connection) throws XMPPException { + public static boolean isSupported(XMPPConnection connection) throws NoResponseException, XMPPErrorException { return AMPManager.isConditionSupported(connection, NAME); } diff --git a/extensions/src/main/java/org/jivesoftware/smackx/amp/AMPManager.java b/extensions/src/main/java/org/jivesoftware/smackx/amp/AMPManager.java index 51e2ab43a..2797edbaa 100644 --- a/extensions/src/main/java/org/jivesoftware/smackx/amp/AMPManager.java +++ b/extensions/src/main/java/org/jivesoftware/smackx/amp/AMPManager.java @@ -16,9 +16,10 @@ */ package org.jivesoftware.smackx.amp; +import org.jivesoftware.smack.SmackException.NoResponseException; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.ConnectionCreationListener; -import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smackx.amp.packet.AMPExtension; import org.jivesoftware.smackx.disco.ServiceDiscoveryManager; import org.jivesoftware.smackx.disco.packet.DiscoverInfo; @@ -83,9 +84,10 @@ public class AMPManager { * @param connection active xmpp connection * @param action action to check * @return true if this action is supported. - * @throws XMPPException + * @throws XMPPErrorException + * @throws NoResponseException */ - public static boolean isActionSupported(XMPPConnection connection, AMPExtension.Action action) throws XMPPException { + public static boolean isActionSupported(XMPPConnection connection, AMPExtension.Action action) throws NoResponseException, XMPPErrorException { String featureName = AMPExtension.NAMESPACE + "?action=" + action.toString(); return isFeatureSupportedByServer(connection, featureName, AMPExtension.NAMESPACE); } @@ -95,17 +97,18 @@ public class AMPManager { * @param connection active xmpp connection * @param conditionName name of condition to check * @return true if this condition is supported. - * @throws XMPPException + * @throws XMPPErrorException + * @throws NoResponseException * @see AMPDeliverCondition * @see AMPExpireAtCondition * @see AMPMatchResourceCondition */ - public static boolean isConditionSupported(XMPPConnection connection, String conditionName) throws XMPPException { + public static boolean isConditionSupported(XMPPConnection connection, String conditionName) throws NoResponseException, XMPPErrorException { String featureName = AMPExtension.NAMESPACE + "?condition=" + conditionName; return isFeatureSupportedByServer(connection, featureName, AMPExtension.NAMESPACE); } - private static boolean isFeatureSupportedByServer(XMPPConnection connection, String featureName, String node) throws XMPPException { + private static boolean isFeatureSupportedByServer(XMPPConnection connection, String featureName, String node) throws NoResponseException, XMPPErrorException { ServiceDiscoveryManager discoveryManager = ServiceDiscoveryManager.getInstanceFor(connection); DiscoverInfo info = discoveryManager.discoverInfo(connection.getServiceName(), node); Iterator it = info.getFeatures(); diff --git a/extensions/src/main/java/org/jivesoftware/smackx/amp/AMPMatchResourceCondition.java b/extensions/src/main/java/org/jivesoftware/smackx/amp/AMPMatchResourceCondition.java index 66d81c0f8..e4987ddb8 100644 --- a/extensions/src/main/java/org/jivesoftware/smackx/amp/AMPMatchResourceCondition.java +++ b/extensions/src/main/java/org/jivesoftware/smackx/amp/AMPMatchResourceCondition.java @@ -16,8 +16,9 @@ */ package org.jivesoftware.smackx.amp; +import org.jivesoftware.smack.SmackException.NoResponseException; import org.jivesoftware.smack.XMPPConnection; -import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smackx.amp.packet.AMPExtension; public class AMPMatchResourceCondition implements AMPExtension.Condition { @@ -28,9 +29,10 @@ public class AMPMatchResourceCondition implements AMPExtension.Condition { * Check if server supports match-resource condition * @param connection Smack connection instance * @return true if match-resource condition is supported. - * @throws XMPPException + * @throws XMPPErrorException + * @throws NoResponseException */ - public static boolean isSupported(XMPPConnection connection) throws XMPPException { + public static boolean isSupported(XMPPConnection connection) throws NoResponseException, XMPPErrorException { return AMPManager.isConditionSupported(connection, NAME); } diff --git a/extensions/src/main/java/org/jivesoftware/smackx/bookmarks/BookmarkManager.java b/extensions/src/main/java/org/jivesoftware/smackx/bookmarks/BookmarkManager.java index 6bf85f418..1ef09cbc2 100644 --- a/extensions/src/main/java/org/jivesoftware/smackx/bookmarks/BookmarkManager.java +++ b/extensions/src/main/java/org/jivesoftware/smackx/bookmarks/BookmarkManager.java @@ -17,8 +17,11 @@ package org.jivesoftware.smackx.bookmarks; +import org.jivesoftware.smack.SmackException; +import org.jivesoftware.smack.SmackException.NoResponseException; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smackx.iqprivate.PrivateDataManager; import java.util.*; @@ -46,13 +49,15 @@ public class BookmarkManager { * @param connection the connection for which the manager is desired. * @return Returns the BookmarkManager for a connection, if it doesn't * exist it is created. - * @throws XMPPException Thrown if the connection is null or has not yet been authenticated. + * @throws XMPPException + * @throws SmackException thrown has not been authenticated. + * @throws IllegalArgumentException when the connection is null. */ public synchronized static BookmarkManager getBookmarkManager(XMPPConnection connection) - throws XMPPException + throws XMPPException, SmackException { BookmarkManager manager = (BookmarkManager) bookmarkManagerMap.get(connection); - if(manager == null) { + if (manager == null) { manager = new BookmarkManager(connection); bookmarkManagerMap.put(connection, manager); } @@ -68,11 +73,15 @@ public class BookmarkManager { * storage:bookmarks namespace. * * @param connection the connection for persisting and retrieving bookmarks. - * @throws XMPPException thrown when the connection is null or has not been authenticated. + * @throws SmackException thrown has not been authenticated. + * @throws IllegalArgumentException when the connection is null. */ - private BookmarkManager(XMPPConnection connection) throws XMPPException { - if(connection == null || !connection.isAuthenticated()) { - throw new XMPPException("Invalid connection."); + private BookmarkManager(XMPPConnection connection) throws XMPPException, SmackException { + if (connection == null) { + throw new IllegalArgumentException("connection must not be null."); + } + if (!connection.isAuthenticated()) { + throw new SmackException("connection not authenticated."); } this.privateDataManager = new PrivateDataManager(connection); } @@ -81,11 +90,11 @@ public class BookmarkManager { * Returns all currently bookmarked conferences. * * @return returns all currently bookmarked conferences - * @throws XMPPException thrown when there was an error retrieving the current bookmarks from - * the server. + * @throws XMPPErrorException + * @throws NoResponseException * @see BookmarkedConference */ - public Collection getBookmarkedConferences() throws XMPPException { + public Collection getBookmarkedConferences() throws NoResponseException, XMPPErrorException { retrieveBookmarks(); return Collections.unmodifiableCollection(bookmarks.getBookmarkedConferences()); } @@ -98,11 +107,12 @@ public class BookmarkManager { * @param isAutoJoin whether or not to join this conference automatically on login * @param nickname the nickname to use for the user when joining the conference * @param password the password to use for the user when joining the conference - * @throws XMPPException thrown when there is an issue retrieving the current bookmarks from + * @throws XMPPErrorException thrown when there is an issue retrieving the current bookmarks from * the server. + * @throws NoResponseException if there was no response from the server. */ public void addBookmarkedConference(String name, String jid, boolean isAutoJoin, - String nickname, String password) throws XMPPException + String nickname, String password) throws NoResponseException, XMPPErrorException { retrieveBookmarks(); BookmarkedConference bookmark @@ -128,12 +138,13 @@ public class BookmarkManager { * Removes a conference from the bookmarks. * * @param jid the jid of the conference to be removed. - * @throws XMPPException thrown when there is a problem with the connection attempting to + * @throws XMPPErrorException thrown when there is a problem with the connection attempting to * retrieve the bookmarks or persist the bookmarks. + * @throws NoResponseException if there was no response from the server. * @throws IllegalArgumentException thrown when the conference being removed is a shared * conference */ - public void removeBookmarkedConference(String jid) throws XMPPException { + public void removeBookmarkedConference(String jid) throws NoResponseException, XMPPErrorException { retrieveBookmarks(); Iterator it = bookmarks.getBookmarkedConferences().iterator(); while(it.hasNext()) { @@ -153,9 +164,10 @@ public class BookmarkManager { * Returns an unmodifiable collection of all bookmarked urls. * * @return returns an unmodifiable collection of all bookmarked urls. - * @throws XMPPException thrown when there is a problem retriving bookmarks from the server. + * @throws XMPPErrorException thrown when there is a problem retriving bookmarks from the server. + * @throws NoResponseException if there was no response from the server. */ - public Collection getBookmarkedURLs() throws XMPPException { + public Collection getBookmarkedURLs() throws NoResponseException, XMPPErrorException { retrieveBookmarks(); return Collections.unmodifiableCollection(bookmarks.getBookmarkedURLS()); } @@ -166,10 +178,11 @@ public class BookmarkManager { * @param URL the url of the bookmark * @param name the name of the bookmark * @param isRSS whether or not the url is an rss feed - * @throws XMPPException thrown when there is an error retriving or saving bookmarks from or to + * @throws XMPPErrorException thrown when there is an error retriving or saving bookmarks from or to * the server + * @throws NoResponseException if there was no response from the server. */ - public void addBookmarkedURL(String URL, String name, boolean isRSS) throws XMPPException { + public void addBookmarkedURL(String URL, String name, boolean isRSS) throws NoResponseException, XMPPErrorException { retrieveBookmarks(); BookmarkedURL bookmark = new BookmarkedURL(URL, name, isRSS); List urls = bookmarks.getBookmarkedURLS(); @@ -191,10 +204,11 @@ public class BookmarkManager { * Removes a url from the bookmarks. * * @param bookmarkURL the url of the bookmark to remove - * @throws XMPPException thrown if there is an error retriving or saving bookmarks from or to + * @throws XMPPErrorException thrown if there is an error retriving or saving bookmarks from or to * the server. + * @throws NoResponseException if there was no response from the server. */ - public void removeBookmarkedURL(String bookmarkURL) throws XMPPException { + public void removeBookmarkedURL(String bookmarkURL) throws NoResponseException, XMPPErrorException { retrieveBookmarks(); Iterator it = bookmarks.getBookmarkedURLS().iterator(); while(it.hasNext()) { @@ -210,7 +224,7 @@ public class BookmarkManager { } } - private Bookmarks retrieveBookmarks() throws XMPPException { + private Bookmarks retrieveBookmarks() throws NoResponseException, XMPPErrorException { synchronized(bookmarkLock) { if(bookmarks == null) { bookmarks = (Bookmarks) privateDataManager.getPrivateData("storage", diff --git a/extensions/src/main/java/org/jivesoftware/smackx/bytestreams/BytestreamManager.java b/extensions/src/main/java/org/jivesoftware/smackx/bytestreams/BytestreamManager.java index 15a979c0d..a91086b86 100644 --- a/extensions/src/main/java/org/jivesoftware/smackx/bytestreams/BytestreamManager.java +++ b/extensions/src/main/java/org/jivesoftware/smackx/bytestreams/BytestreamManager.java @@ -18,6 +18,7 @@ package org.jivesoftware.smackx.bytestreams; import java.io.IOException; +import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamManager; import org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamManager; @@ -94,7 +95,7 @@ public interface BytestreamManager { * operation */ public BytestreamSession establishSession(String targetJID) throws XMPPException, IOException, - InterruptedException; + InterruptedException, SmackException; /** * Establishes a bytestream with the given user and returns the session to send/receive data @@ -112,6 +113,6 @@ public interface BytestreamManager { * operation */ public BytestreamSession establishSession(String targetJID, String sessionID) - throws XMPPException, IOException, InterruptedException; + throws XMPPException, IOException, InterruptedException, SmackException; } diff --git a/extensions/src/main/java/org/jivesoftware/smackx/bytestreams/BytestreamRequest.java b/extensions/src/main/java/org/jivesoftware/smackx/bytestreams/BytestreamRequest.java index 94f9280a3..10622e173 100644 --- a/extensions/src/main/java/org/jivesoftware/smackx/bytestreams/BytestreamRequest.java +++ b/extensions/src/main/java/org/jivesoftware/smackx/bytestreams/BytestreamRequest.java @@ -16,7 +16,9 @@ */ package org.jivesoftware.smackx.bytestreams; -import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.SmackException; +import org.jivesoftware.smack.SmackException.NoResponseException; +import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamRequest; import org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamRequest; @@ -48,11 +50,13 @@ public interface BytestreamRequest { * Accepts the bytestream open request and returns the session to send/receive data. * * @return the session to send/receive data - * @throws XMPPException if an error occurred while accepting the bytestream request + * @throws XMPPErrorException if an error occurred while accepting the bytestream request * @throws InterruptedException if the thread was interrupted while waiting in a blocking * operation + * @throws NoResponseException + * @throws SmackException */ - public BytestreamSession accept() throws XMPPException, InterruptedException; + public BytestreamSession accept() throws InterruptedException, NoResponseException, XMPPErrorException, SmackException; /** * Rejects the bytestream request by sending a reject error to the initiator. diff --git a/extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamManager.java b/extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamManager.java index d5a6ee7a7..ef79c1422 100644 --- a/extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamManager.java +++ b/extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamManager.java @@ -25,9 +25,12 @@ import java.util.Random; import java.util.concurrent.ConcurrentHashMap; import org.jivesoftware.smack.AbstractConnectionListener; +import org.jivesoftware.smack.SmackException; +import org.jivesoftware.smack.SmackException.NoResponseException; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.ConnectionCreationListener; import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.XMPPError; import org.jivesoftware.smackx.bytestreams.BytestreamListener; @@ -405,8 +408,9 @@ public class InBandBytestreamManager implements BytestreamManager { * @return the session to send/receive data to/from the user * @throws XMPPException if the user doesn't support or accept in-band bytestreams, or if the * user prefers smaller block sizes + * @throws SmackException if there was no response from the server. */ - public InBandBytestreamSession establishSession(String targetJID) throws XMPPException { + public InBandBytestreamSession establishSession(String targetJID) throws XMPPException, SmackException { String sessionID = getNextSessionID(); return establishSession(targetJID, sessionID); } @@ -418,11 +422,12 @@ public class InBandBytestreamManager implements BytestreamManager { * @param targetJID the JID of the user an In-Band Bytestream should be established * @param sessionID the session ID for the In-Band Bytestream request * @return the session to send/receive data to/from the user - * @throws XMPPException if the user doesn't support or accept in-band bytestreams, or if the + * @throws XMPPErrorException if the user doesn't support or accept in-band bytestreams, or if the * user prefers smaller block sizes + * @throws NoResponseException if there was no response from the server. */ public InBandBytestreamSession establishSession(String targetJID, String sessionID) - throws XMPPException { + throws NoResponseException, XMPPErrorException { Open byteStreamRequest = new Open(sessionID, this.defaultBlockSize, this.stanza); byteStreamRequest.setTo(targetJID); diff --git a/extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamRequest.java b/extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamRequest.java index 6e3e39ccc..e989f984b 100644 --- a/extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamRequest.java +++ b/extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamRequest.java @@ -17,7 +17,6 @@ package org.jivesoftware.smackx.bytestreams.ibb; import org.jivesoftware.smack.XMPPConnection; -import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smackx.bytestreams.BytestreamRequest; import org.jivesoftware.smackx.bytestreams.ibb.packet.Open; @@ -67,9 +66,8 @@ public class InBandBytestreamRequest implements BytestreamRequest { * send/receive data. * * @return the session to send/receive data - * @throws XMPPException if stream is invalid. */ - public InBandBytestreamSession accept() throws XMPPException { + public InBandBytestreamSession accept() { XMPPConnection connection = this.manager.getConnection(); // create In-Band Bytestream session and store it diff --git a/extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamSession.java b/extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamSession.java index 17f0b003c..4c033d7b7 100644 --- a/extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamSession.java +++ b/extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamSession.java @@ -26,7 +26,6 @@ import java.util.concurrent.TimeUnit; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.PacketListener; -import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.filter.AndFilter; import org.jivesoftware.smack.filter.PacketFilter; import org.jivesoftware.smack.filter.PacketTypeFilter; @@ -211,8 +210,10 @@ public class InBandBytestreamSession implements BytestreamSession { try { connection.createPacketCollectorAndSend(close).nextResultOrThrow(); } - catch (XMPPException e) { - throw new IOException("Error while closing stream: " + e.getMessage()); + catch (Exception e) { + // Sadly we are unable to wrap the exception within the IOException, because the + // IOException(String,Throwable) constructor is only support from Android API 9 on. + throw new IOException(); } this.inputStream.cleanup(); @@ -764,11 +765,13 @@ public class InBandBytestreamSession implements BytestreamSession { try { connection.createPacketCollectorAndSend(iq).nextResultOrThrow(); } - catch (XMPPException e) { + catch (Exception e) { // close session unless it is already closed if (!this.isClosed) { InBandBytestreamSession.this.close(); - throw new IOException("Error while sending Data: " + e.getMessage()); + // Sadly we are unable to wrap the exception within the IOException, because the + // IOException(String,Throwable) constructor is only support from Android API 9 on. + throw new IOException(); } } diff --git a/extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5BytestreamManager.java b/extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5BytestreamManager.java index 7b392951c..85b04c1b1 100644 --- a/extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5BytestreamManager.java +++ b/extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5BytestreamManager.java @@ -30,9 +30,12 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeoutException; import org.jivesoftware.smack.AbstractConnectionListener; +import org.jivesoftware.smack.SmackException; +import org.jivesoftware.smack.SmackException.NoResponseException; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.ConnectionCreationListener; import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.Packet; import org.jivesoftware.smack.packet.XMPPError; @@ -406,9 +409,10 @@ public final class Socks5BytestreamManager implements BytestreamManager { * Proxy could be found, if the user couldn't connect to any of the SOCKS5 Proxies * @throws IOException if the bytestream could not be established * @throws InterruptedException if the current thread was interrupted while waiting + * @throws SmackException if there was no response from the server. */ public Socks5BytestreamSession establishSession(String targetJID) throws XMPPException, - IOException, InterruptedException { + IOException, InterruptedException, SmackException { String sessionID = getNextSessionID(); return establishSession(targetJID, sessionID); } @@ -420,25 +424,26 @@ public final class Socks5BytestreamManager implements BytestreamManager { * @param targetJID the JID of the user a SOCKS5 Bytestream should be established * @param sessionID the session ID for the SOCKS5 Bytestream request * @return the Socket to send/receive data to/from the user - * @throws XMPPException if the user doesn't support or accept SOCKS5 Bytestreams, if no Socks5 - * Proxy could be found, if the user couldn't connect to any of the SOCKS5 Proxies * @throws IOException if the bytestream could not be established * @throws InterruptedException if the current thread was interrupted while waiting + * @throws NoResponseException + * @throws SmackException if the target does not support SOCKS5. + * @throws XMPPException */ public Socks5BytestreamSession establishSession(String targetJID, String sessionID) - throws XMPPException, IOException, InterruptedException { + throws IOException, InterruptedException, NoResponseException, SmackException, XMPPException{ - XMPPException discoveryException = null; + XMPPErrorException discoveryException = null; // check if target supports SOCKS5 Bytestream if (!supportsSocks5(targetJID)) { - throw new XMPPException(targetJID + " doesn't support SOCKS5 Bytestream"); + throw new SmackException(targetJID + " doesn't support SOCKS5 Bytestream"); } List proxies = new ArrayList(); // determine SOCKS5 proxies from XMPP-server try { proxies.addAll(determineProxies()); - } catch (XMPPException e) { + } catch (XMPPErrorException e) { // don't abort here, just remember the exception thrown by determineProxies() // determineStreamHostInfos() will at least add the local Socks5 proxy (if enabled) discoveryException = e; @@ -448,7 +453,11 @@ public final class Socks5BytestreamManager implements BytestreamManager { List streamHosts = determineStreamHostInfos(proxies); if (streamHosts.isEmpty()) { - throw discoveryException != null ? discoveryException : new XMPPException("no SOCKS5 proxies available"); + if (discoveryException != null) { + throw discoveryException; + } else { + throw new SmackException("no SOCKS5 proxies available"); + } } // compute digest @@ -488,7 +497,7 @@ public final class Socks5BytestreamManager implements BytestreamManager { StreamHost usedStreamHost = initiation.getStreamHost(streamHostUsed.getJID()); if (usedStreamHost == null) { - throw new XMPPException("Remote user responded with unknown host"); + throw new SmackException("Remote user responded with unknown host"); } // build SOCKS5 client @@ -524,12 +533,11 @@ public final class Socks5BytestreamManager implements BytestreamManager { * @param targetJID the target JID * @return true if the given target JID supports feature SOCKS5 Bytestream * otherwise false - * @throws XMPPException if there was an error querying target for supported features + * @throws XMPPErrorException + * @throws NoResponseException */ - private boolean supportsSocks5(String targetJID) throws XMPPException { - ServiceDiscoveryManager serviceDiscoveryManager = ServiceDiscoveryManager.getInstanceFor(this.connection); - DiscoverInfo discoverInfo = serviceDiscoveryManager.discoverInfo(targetJID); - return discoverInfo.containsFeature(NAMESPACE); + private boolean supportsSocks5(String targetJID) throws NoResponseException, XMPPErrorException { + return ServiceDiscoveryManager.getInstanceFor(connection).supportsFeature(targetJID, NAMESPACE); } /** @@ -537,9 +545,10 @@ public final class Socks5BytestreamManager implements BytestreamManager { * in the same order as returned by the XMPP server. * * @return list of JIDs of SOCKS5 proxies - * @throws XMPPException if there was an error querying the XMPP server for SOCKS5 proxies + * @throws XMPPErrorException if there was an error querying the XMPP server for SOCKS5 proxies + * @throws NoResponseException if there was no response from the server. */ - private List determineProxies() throws XMPPException { + private List determineProxies() throws NoResponseException, XMPPErrorException { ServiceDiscoveryManager serviceDiscoveryManager = ServiceDiscoveryManager.getInstanceFor(this.connection); List proxies = new ArrayList(); @@ -615,7 +624,7 @@ public final class Socks5BytestreamManager implements BytestreamManager { streamHostRequest).nextResultOrThrow(); streamHosts.addAll(response.getStreamHosts()); } - catch (XMPPException e) { + catch (Exception e) { // blacklist errornous proxies this.proxyBlacklist.add(proxy); } diff --git a/extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5BytestreamRequest.java b/extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5BytestreamRequest.java index 73dce1a78..88f591450 100644 --- a/extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5BytestreamRequest.java +++ b/extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5BytestreamRequest.java @@ -21,7 +21,9 @@ import java.net.Socket; import java.util.Collection; import java.util.concurrent.TimeoutException; +import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.XMPPError; import org.jivesoftware.smack.util.Cache; @@ -186,10 +188,11 @@ public class Socks5BytestreamRequest implements BytestreamRequest { * {@link #setTotalConnectTimeout(int)} and {@link #setMinimumConnectTimeout(int)}. * * @return the socket to send/receive data - * @throws XMPPException if connection to all SOCKS5 proxies failed or if stream is invalid. * @throws InterruptedException if the current thread was interrupted while waiting + * @throws XMPPErrorException + * @throws SmackException */ - public Socks5BytestreamSession accept() throws XMPPException, InterruptedException { + public Socks5BytestreamSession accept() throws InterruptedException, XMPPErrorException, SmackException { Collection streamHosts = this.bytestreamRequest.getStreamHosts(); // throw exceptions if request contains no stream hosts @@ -269,15 +272,14 @@ public class Socks5BytestreamRequest implements BytestreamRequest { /** * Cancels the SOCKS5 Bytestream request by sending an error to the initiator and building a * XMPP exception. - * - * @throws XMPPException XMPP exception containing the XMPP error + * @throws XMPPErrorException */ - private void cancelRequest() throws XMPPException { + private void cancelRequest() throws XMPPErrorException { String errorMessage = "Could not establish socket with any provided host"; XMPPError error = new XMPPError(XMPPError.Condition.item_not_found, errorMessage); IQ errorIQ = IQ.createErrorResponse(this.bytestreamRequest, error); this.manager.getConnection().sendPacket(errorIQ); - throw new XMPPException(errorMessage, error); + throw new XMPPErrorException(errorMessage, error); } /** diff --git a/extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5Client.java b/extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5Client.java index 5e538b68a..13e74c4f2 100644 --- a/extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5Client.java +++ b/extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5Client.java @@ -29,7 +29,9 @@ import java.util.concurrent.FutureTask; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; +import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream.StreamHost; /** @@ -65,17 +67,19 @@ class Socks5Client { * @param timeout timeout to connect to SOCKS5 proxy in milliseconds * @return socket the initialized socket * @throws IOException if initializing the socket failed due to a network error - * @throws XMPPException if establishing connection to SOCKS5 proxy failed + * @throws XMPPErrorException if establishing connection to SOCKS5 proxy failed * @throws TimeoutException if connecting to SOCKS5 proxy timed out * @throws InterruptedException if the current thread was interrupted while waiting + * @throws SmackException if the connection to the SOC + * @throws XMPPException */ - public Socket getSocket(int timeout) throws IOException, XMPPException, InterruptedException, - TimeoutException { + public Socket getSocket(int timeout) throws IOException, XMPPErrorException, InterruptedException, + TimeoutException, SmackException, XMPPException { // wrap connecting in future for timeout FutureTask futureTask = new FutureTask(new Callable() { - public Socket call() throws Exception { + public Socket call() throws IOException, SmackException { // initialize socket Socket socket = new Socket(); @@ -83,16 +87,23 @@ class Socks5Client { streamHost.getPort()); socket.connect(socketAddress); + boolean res; // initialize connection to SOCKS5 proxy - if (!establish(socket)) { - - // initialization failed, close socket + try { + res = establish(socket); + } + catch (SmackException e) { socket.close(); - throw new XMPPException("establishing connection to SOCKS5 proxy failed"); - + throw e; } - return socket; + if (res) { + return socket; + } + else { + socket.close(); + throw new SmackException("SOCKS5 negotiation failed"); + } } }); @@ -110,8 +121,8 @@ class Socks5Client { if (cause instanceof IOException) { throw (IOException) cause; } - if (cause instanceof XMPPException) { - throw (XMPPException) cause; + if (cause instanceof SmackException) { + throw (SmackException) cause; } } @@ -132,49 +143,49 @@ class Socks5Client { * @param socket connected to a SOCKS5 proxy * @return true if if a stream could be established, otherwise false. * If false is returned the given Socket should be closed. - * @throws IOException if a network error occurred + * @throws SmackException */ - protected boolean establish(Socket socket) throws IOException { + protected boolean establish(Socket socket) throws SmackException { + byte[] connectionRequest; + byte[] connectionResponse; /* * use DataInputStream/DataOutpuStream to assure read and write is completed in a single * statement */ - DataInputStream in = new DataInputStream(socket.getInputStream()); - DataOutputStream out = new DataOutputStream(socket.getOutputStream()); - - // authentication negotiation - byte[] cmd = new byte[3]; - - cmd[0] = (byte) 0x05; // protocol version 5 - cmd[1] = (byte) 0x01; // number of authentication methods supported - cmd[2] = (byte) 0x00; // authentication method: no-authentication required - - out.write(cmd); - out.flush(); - - byte[] response = new byte[2]; - in.readFully(response); - - // check if server responded with correct version and no-authentication method - if (response[0] != (byte) 0x05 || response[1] != (byte) 0x00) { - return false; - } - - // request SOCKS5 connection with given address/digest - byte[] connectionRequest = createSocks5ConnectRequest(); - out.write(connectionRequest); - out.flush(); - - // receive response - byte[] connectionResponse; try { + DataInputStream in = new DataInputStream(socket.getInputStream()); + DataOutputStream out = new DataOutputStream(socket.getOutputStream()); + + // authentication negotiation + byte[] cmd = new byte[3]; + + cmd[0] = (byte) 0x05; // protocol version 5 + cmd[1] = (byte) 0x01; // number of authentication methods supported + cmd[2] = (byte) 0x00; // authentication method: no-authentication required + + out.write(cmd); + out.flush(); + + byte[] response = new byte[2]; + in.readFully(response); + + // check if server responded with correct version and no-authentication method + if (response[0] != (byte) 0x05 || response[1] != (byte) 0x00) { + return false; + } + + // request SOCKS5 connection with given address/digest + connectionRequest = createSocks5ConnectRequest(); + out.write(connectionRequest); + out.flush(); + + // receive response connectionResponse = Socks5Utils.receiveSocks5Message(in); } - catch (XMPPException e) { - return false; // server answered in an unsupported way + catch (IOException e) { + throw new SmackException(e); } - // verify response connectionRequest[1] = (byte) 0x00; // set expected return status to 0 return Arrays.equals(connectionRequest, connectionResponse); diff --git a/extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5ClientForInitiator.java b/extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5ClientForInitiator.java index 956722105..b2db04b4c 100644 --- a/extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5ClientForInitiator.java +++ b/extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5ClientForInitiator.java @@ -20,8 +20,11 @@ import java.io.IOException; import java.net.Socket; import java.util.concurrent.TimeoutException; +import org.jivesoftware.smack.SmackException; +import org.jivesoftware.smack.SmackException.NoResponseException; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream; import org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream.StreamHost; @@ -62,8 +65,8 @@ class Socks5ClientForInitiator extends Socks5Client { this.target = target; } - public Socket getSocket(int timeout) throws IOException, XMPPException, InterruptedException, - TimeoutException { + public Socket getSocket(int timeout) throws IOException, InterruptedException, + TimeoutException, XMPPException, SmackException { Socket socket = null; // check if stream host is the local SOCKS5 proxy @@ -71,7 +74,7 @@ class Socks5ClientForInitiator extends Socks5Client { Socks5Proxy socks5Server = Socks5Proxy.getSocks5Proxy(); socket = socks5Server.getSocket(this.digest); if (socket == null) { - throw new XMPPException("target is not connected to SOCKS5 proxy"); + throw new SmackException("target is not connected to SOCKS5 proxy"); } } else { @@ -80,9 +83,13 @@ class Socks5ClientForInitiator extends Socks5Client { try { activate(); } - catch (XMPPException e) { + catch (XMPPException e1) { socket.close(); - throw new XMPPException("activating SOCKS5 Bytestream failed", e); + throw e1; + } + catch (NoResponseException e2) { + socket.close(); + throw e2; } } @@ -93,8 +100,11 @@ class Socks5ClientForInitiator extends Socks5Client { /** * Activates the SOCKS5 Bytestream by sending a XMPP SOCKS5 Bytestream activation packet to the * SOCKS5 proxy. + * @throws XMPPErrorException + * @throws NoResponseException + * @throws SmackException if there was no response from the server. */ - private void activate() throws XMPPException { + private void activate() throws NoResponseException, XMPPErrorException { Bytestream activate = createStreamHostActivation(); // if activation fails #nextResultOrThrow() throws an exception connection.createPacketCollectorAndSend(activate).nextResultOrThrow(); diff --git a/extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5Proxy.java b/extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5Proxy.java index 77fd2d580..08a0abfff 100644 --- a/extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5Proxy.java +++ b/extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5Proxy.java @@ -35,7 +35,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.logging.Level; import java.util.logging.Logger; -import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.SmackException; /** * The Socks5Proxy class represents a local SOCKS5 proxy server. It can be enabled/disabled by @@ -392,17 +392,17 @@ public class Socks5Proxy { * Negotiates a SOCKS5 connection and stores it on success. * * @param socket connection to the client - * @throws XMPPException if client requests a connection in an unsupported way + * @throws SmackException if client requests a connection in an unsupported way * @throws IOException if a network error occurred */ - private void establishConnection(Socket socket) throws XMPPException, IOException { + private void establishConnection(Socket socket) throws SmackException, IOException { DataOutputStream out = new DataOutputStream(socket.getOutputStream()); DataInputStream in = new DataInputStream(socket.getInputStream()); // first byte is version should be 5 int b = in.read(); if (b != 5) { - throw new XMPPException("Only SOCKS5 supported"); + throw new SmackException("Only SOCKS5 supported"); } // second byte number of authentication methods supported @@ -428,7 +428,7 @@ public class Socks5Proxy { authMethodSelectionResponse[1] = (byte) 0xFF; // no acceptable methods out.write(authMethodSelectionResponse); out.flush(); - throw new XMPPException("Authentication method not supported"); + throw new SmackException("Authentication method not supported"); } authMethodSelectionResponse[1] = (byte) 0x00; // no-authentication method @@ -447,7 +447,7 @@ public class Socks5Proxy { out.write(connectionRequest); out.flush(); - throw new XMPPException("XMPPConnection is not allowed"); + throw new SmackException("Connection is not allowed"); } connectionRequest[1] = (byte) 0x00; // set return status to 0 (success) diff --git a/extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5Utils.java b/extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5Utils.java index 9c7cc490c..82642d9a0 100644 --- a/extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5Utils.java +++ b/extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5Utils.java @@ -19,7 +19,7 @@ package org.jivesoftware.smackx.bytestreams.socks5; import java.io.DataInputStream; import java.io.IOException; -import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.util.StringUtils; /** @@ -53,14 +53,14 @@ class Socks5Utils { * @param in the DataInputStream to read the message from * @return the SOCKS5 message * @throws IOException if a network error occurred - * @throws XMPPException if the SOCKS5 message contains an unsupported address type + * @throws SmackException if the SOCKS5 message contains an unsupported address type */ - public static byte[] receiveSocks5Message(DataInputStream in) throws IOException, XMPPException { + public static byte[] receiveSocks5Message(DataInputStream in) throws IOException, SmackException { byte[] header = new byte[5]; in.readFully(header, 0, 5); if (header[3] != (byte) 0x03) { - throw new XMPPException("Unsupported SOCKS5 address type"); + throw new SmackException("Unsupported SOCKS5 address type"); } int addressLength = header[4]; diff --git a/extensions/src/main/java/org/jivesoftware/smackx/caps/EntityCapsManager.java b/extensions/src/main/java/org/jivesoftware/smackx/caps/EntityCapsManager.java index 42c38b42b..7f18d86ff 100644 --- a/extensions/src/main/java/org/jivesoftware/smackx/caps/EntityCapsManager.java +++ b/extensions/src/main/java/org/jivesoftware/smackx/caps/EntityCapsManager.java @@ -17,12 +17,13 @@ package org.jivesoftware.smackx.caps; import org.jivesoftware.smack.AbstractConnectionListener; +import org.jivesoftware.smack.SmackException.NoResponseException; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.ConnectionCreationListener; import org.jivesoftware.smack.Manager; import org.jivesoftware.smack.PacketInterceptor; import org.jivesoftware.smack.PacketListener; -import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.Packet; import org.jivesoftware.smack.packet.PacketExtension; @@ -391,8 +392,10 @@ public class EntityCapsManager extends Manager { * * @param jid * @return true if the entity supports Entity Capabilities. + * @throws XMPPErrorException + * @throws NoResponseException */ - public boolean areEntityCapsSupported(String jid) throws XMPPException { + public boolean areEntityCapsSupported(String jid) throws NoResponseException, XMPPErrorException { return sdm.supportsFeature(jid, NAMESPACE); } @@ -400,8 +403,10 @@ public class EntityCapsManager extends Manager { * Returns true if Entity Caps are supported by the local service/server * * @return true if the user's server supports Entity Capabilities. + * @throws XMPPErrorException + * @throws NoResponseException */ - public boolean areEntityCapsSupportedByServer() throws XMPPException { + public boolean areEntityCapsSupportedByServer() throws NoResponseException, XMPPErrorException { return areEntityCapsSupported(connection().getServiceName()); } diff --git a/extensions/src/main/java/org/jivesoftware/smackx/caps/provider/CapsExtensionProvider.java b/extensions/src/main/java/org/jivesoftware/smackx/caps/provider/CapsExtensionProvider.java index 9f27301ee..d6ec9c017 100644 --- a/extensions/src/main/java/org/jivesoftware/smackx/caps/provider/CapsExtensionProvider.java +++ b/extensions/src/main/java/org/jivesoftware/smackx/caps/provider/CapsExtensionProvider.java @@ -1,6 +1,6 @@ /** * - * Copyright © 2009 Jonas Ådahl, 2011-2013 Florian Schmaus + * Copyright © 2009 Jonas Ådahl, 2011-2014 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +18,7 @@ package org.jivesoftware.smackx.caps.provider; import java.io.IOException; -import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.packet.PacketExtension; import org.jivesoftware.smack.provider.PacketExtensionProvider; import org.jivesoftware.smackx.caps.EntityCapsManager; @@ -29,7 +29,7 @@ import org.xmlpull.v1.XmlPullParserException; public class CapsExtensionProvider implements PacketExtensionProvider { public PacketExtension parseExtension(XmlPullParser parser) throws XmlPullParserException, IOException, - XMPPException { + SmackException { String hash = null; String version = null; String node = null; @@ -39,20 +39,20 @@ public class CapsExtensionProvider implements PacketExtensionProvider { version = parser.getAttributeValue(null, "ver"); node = parser.getAttributeValue(null, "node"); } else { - throw new XMPPException("Malformed Caps element"); + throw new SmackException("Malformed Caps element"); } parser.next(); if (!(parser.getEventType() == XmlPullParser.END_TAG && parser.getName().equalsIgnoreCase(EntityCapsManager.ELEMENT))) { - throw new XMPPException("Malformed nested Caps element"); + throw new SmackException("Malformed nested Caps element"); } if (hash != null && version != null && node != null) { return new CapsExtension(node, version, hash); } else { - throw new XMPPException("Caps elment with missing attributes"); + throw new SmackException("Caps elment with missing attributes"); } } } diff --git a/extensions/src/main/java/org/jivesoftware/smackx/commands/AdHocCommand.java b/extensions/src/main/java/org/jivesoftware/smackx/commands/AdHocCommand.java index 5a48c9ed4..27b7103dc 100755 --- a/extensions/src/main/java/org/jivesoftware/smackx/commands/AdHocCommand.java +++ b/extensions/src/main/java/org/jivesoftware/smackx/commands/AdHocCommand.java @@ -16,7 +16,8 @@ */ package org.jivesoftware.smackx.commands; -import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.SmackException.NoResponseException; +import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.packet.XMPPError; import org.jivesoftware.smackx.commands.packet.AdHocCommandData; import org.jivesoftware.smackx.xdata.Form; @@ -207,9 +208,9 @@ public abstract class AdHocCommand { * command. It is invoked on every command. If there is a problem executing * the command it throws an XMPPException. * - * @throws XMPPException if there is an error executing the command. + * @throws XMPPErrorException if there is an error executing the command. */ - public abstract void execute() throws XMPPException; + public abstract void execute() throws NoResponseException, XMPPErrorException; /** * Executes the next action of the command with the information provided in @@ -219,9 +220,9 @@ public abstract class AdHocCommand { * XMPPException. * * @param response the form answer of the previous stage. - * @throws XMPPException if there is a problem executing the command. + * @throws XMPPErrorException if there is a problem executing the command. */ - public abstract void next(Form response) throws XMPPException; + public abstract void next(Form response) throws NoResponseException, XMPPErrorException; /** * Completes the command execution with the information provided in the @@ -231,9 +232,9 @@ public abstract class AdHocCommand { * XMPPException. * * @param response the form answer of the previous stage. - * @throws XMPPException if there is a problem executing the command. + * @throws XMPPErrorException if there is a problem executing the command. */ - public abstract void complete(Form response) throws XMPPException; + public abstract void complete(Form response) throws NoResponseException, XMPPErrorException; /** * Goes to the previous stage. The requester is asking to re-send the @@ -241,18 +242,18 @@ public abstract class AdHocCommand { * the previous one. If there is a problem executing the command it throws * an XMPPException. * - * @throws XMPPException if there is a problem executing the command. + * @throws XMPPErrorException if there is a problem executing the command. */ - public abstract void prev() throws XMPPException; + public abstract void prev() throws NoResponseException, XMPPErrorException; /** * Cancels the execution of the command. This can be invoked on any stage of * the execution. If there is a problem executing the command it throws an * XMPPException. * - * @throws XMPPException if there is a problem executing the command. + * @throws XMPPErrorException if there is a problem executing the command. */ - public abstract void cancel() throws XMPPException; + public abstract void cancel() throws NoResponseException, XMPPErrorException; /** * Returns a collection with the allowed actions based on the current stage. diff --git a/extensions/src/main/java/org/jivesoftware/smackx/commands/AdHocCommandManager.java b/extensions/src/main/java/org/jivesoftware/smackx/commands/AdHocCommandManager.java index 0465fd272..daf9f8791 100755 --- a/extensions/src/main/java/org/jivesoftware/smackx/commands/AdHocCommandManager.java +++ b/extensions/src/main/java/org/jivesoftware/smackx/commands/AdHocCommandManager.java @@ -18,6 +18,7 @@ package org.jivesoftware.smackx.commands; import org.jivesoftware.smack.*; +import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.filter.PacketFilter; import org.jivesoftware.smack.filter.PacketTypeFilter; import org.jivesoftware.smack.packet.IQ; @@ -171,7 +172,12 @@ public class AdHocCommandManager extends Manager { PacketListener listener = new PacketListener() { public void processPacket(Packet packet) { AdHocCommandData requestData = (AdHocCommandData) packet; - processAdHocCommand(requestData); + try { + processAdHocCommand(requestData); + } + catch (SmackException e) { + return; + } } }; @@ -256,8 +262,9 @@ public class AdHocCommandManager extends Manager { * @param jid the full JID to retrieve the commands for. * @return the discovered items. * @throws XMPPException if the operation failed for some reason. + * @throws SmackException if there was no response from the server. */ - public DiscoverItems discoverCommands(String jid) throws XMPPException { + public DiscoverItems discoverCommands(String jid) throws XMPPException, SmackException { return serviceDiscoveryManager.discoverItems(jid, NAMESPACE); } @@ -266,8 +273,9 @@ public class AdHocCommandManager extends Manager { * * @param jid the full JID to publish the commands to. * @throws XMPPException if the operation failed for some reason. + * @throws SmackException if there was no response from the server. */ - public void publishCommands(String jid) throws XMPPException { + public void publishCommands(String jid) throws XMPPException, SmackException { // Collects the commands to publish as items DiscoverItems discoverItems = new DiscoverItems(); Collection xCommandsList = getRegisteredCommands(); @@ -319,8 +327,9 @@ public class AdHocCommandManager extends Manager { * * @param requestData * the packet to process. + * @throws SmackException if there was no response from the server. */ - private void processAdHocCommand(AdHocCommandData requestData) { + private void processAdHocCommand(AdHocCommandData requestData) throws SmackException { // Only process requests of type SET if (requestData.getType() != IQ.Type.SET) { return; @@ -444,7 +453,7 @@ public class AdHocCommandManager extends Manager { connection().sendPacket(response); } - catch (XMPPException e) { + catch (XMPPErrorException e) { // If there is an exception caused by the next, complete, // prev or cancel method, then that error is returned to the // requester. @@ -558,7 +567,7 @@ public class AdHocCommandManager extends Manager { connection().sendPacket(response); } - catch (XMPPException e) { + catch (XMPPErrorException e) { // If there is an exception caused by the next, complete, // prev or cancel method, then that error is returned to the // requester. @@ -621,10 +630,9 @@ public class AdHocCommandManager extends Manager { * @param commandNode the command node that identifies it. * @param sessionID the session id of this execution. * @return the command instance to execute. - * @throws XMPPException if there is problem creating the new instance. + * @throws XMPPErrorException if there is problem creating the new instance. */ - private LocalCommand newInstanceOfCmd(String commandNode, String sessionID) - throws XMPPException + private LocalCommand newInstanceOfCmd(String commandNode, String sessionID) throws XMPPErrorException { AdHocCommandInfo commandInfo = commands.get(commandNode); LocalCommand command; @@ -635,11 +643,11 @@ public class AdHocCommandManager extends Manager { command.setNode(commandInfo.getNode()); } catch (InstantiationException e) { - throw new XMPPException(new XMPPError( + throw new XMPPErrorException(new XMPPError( XMPPError.Condition.internal_server_error)); } catch (IllegalAccessException e) { - throw new XMPPException(new XMPPError( + throw new XMPPErrorException(new XMPPError( XMPPError.Condition.internal_server_error)); } return command; diff --git a/extensions/src/main/java/org/jivesoftware/smackx/commands/RemoteCommand.java b/extensions/src/main/java/org/jivesoftware/smackx/commands/RemoteCommand.java index 101fb6922..b36dc2739 100755 --- a/extensions/src/main/java/org/jivesoftware/smackx/commands/RemoteCommand.java +++ b/extensions/src/main/java/org/jivesoftware/smackx/commands/RemoteCommand.java @@ -17,8 +17,9 @@ package org.jivesoftware.smackx.commands; import org.jivesoftware.smack.SmackConfiguration; +import org.jivesoftware.smack.SmackException.NoResponseException; import org.jivesoftware.smack.XMPPConnection; -import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smackx.commands.packet.AdHocCommandData; import org.jivesoftware.smackx.xdata.Form; @@ -79,17 +80,17 @@ public class RemoteCommand extends AdHocCommand { } @Override - public void cancel() throws XMPPException { + public void cancel() throws NoResponseException, XMPPErrorException { executeAction(Action.cancel, packetReplyTimeout); } @Override - public void complete(Form form) throws XMPPException { + public void complete(Form form) throws NoResponseException, XMPPErrorException { executeAction(Action.complete, form, packetReplyTimeout); } @Override - public void execute() throws XMPPException { + public void execute() throws NoResponseException, XMPPErrorException { executeAction(Action.execute, packetReplyTimeout); } @@ -99,23 +100,24 @@ public class RemoteCommand extends AdHocCommand { * there is a problem executing the command it throws an XMPPException. * * @param form the form anwser of the previous stage. - * @throws XMPPException if an error occurs. + * @throws XMPPErrorException if an error occurs. + * @throws NoResponseException if there was no response from the server. */ - public void execute(Form form) throws XMPPException { + public void execute(Form form) throws NoResponseException, XMPPErrorException { executeAction(Action.execute, form, packetReplyTimeout); } @Override - public void next(Form form) throws XMPPException { + public void next(Form form) throws NoResponseException, XMPPErrorException { executeAction(Action.next, form, packetReplyTimeout); } @Override - public void prev() throws XMPPException { + public void prev() throws NoResponseException, XMPPErrorException { executeAction(Action.prev, packetReplyTimeout); } - private void executeAction(Action action, long packetReplyTimeout) throws XMPPException { + private void executeAction(Action action, long packetReplyTimeout) throws NoResponseException, XMPPErrorException { executeAction(action, null, packetReplyTimeout); } @@ -127,9 +129,10 @@ public class RemoteCommand extends AdHocCommand { * @param action the action to execute. * @param form the form with the information. * @param timeout the amount of time to wait for a reply. - * @throws XMPPException if there is a problem executing the command. + * @throws XMPPErrorException if there is a problem executing the command. + * @throws NoResponseException if there was no response from the server. */ - private void executeAction(Action action, Form form, long timeout) throws XMPPException { + private void executeAction(Action action, Form form, long timeout) throws NoResponseException, XMPPErrorException { // TODO: Check that all the required fields of the form were filled, if // TODO: not throw the corresponding exeption. This will make a faster response, // TODO: since the request is stoped before it's sent. diff --git a/extensions/src/main/java/org/jivesoftware/smackx/disco/ServiceDiscoveryManager.java b/extensions/src/main/java/org/jivesoftware/smackx/disco/ServiceDiscoveryManager.java index b5cd4751b..53828d9a3 100644 --- a/extensions/src/main/java/org/jivesoftware/smackx/disco/ServiceDiscoveryManager.java +++ b/extensions/src/main/java/org/jivesoftware/smackx/disco/ServiceDiscoveryManager.java @@ -17,11 +17,12 @@ package org.jivesoftware.smackx.disco; +import org.jivesoftware.smack.SmackException.NoResponseException; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.ConnectionCreationListener; import org.jivesoftware.smack.Manager; import org.jivesoftware.smack.PacketListener; -import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.filter.PacketFilter; import org.jivesoftware.smack.filter.PacketTypeFilter; import org.jivesoftware.smack.packet.IQ; @@ -493,9 +494,10 @@ public class ServiceDiscoveryManager extends Manager { * * @param entityID the address of the XMPP entity or null. * @return the discovered information. - * @throws XMPPException if the operation failed for some reason. + * @throws XMPPErrorException + * @throws NoResponseException */ - public DiscoverInfo discoverInfo(String entityID) throws XMPPException { + public DiscoverInfo discoverInfo(String entityID) throws NoResponseException, XMPPErrorException { if (entityID == null) return discoverInfo(null, null); @@ -536,9 +538,10 @@ public class ServiceDiscoveryManager extends Manager { * @param entityID the address of the XMPP entity. * @param node the optional attribute that supplements the 'jid' attribute. * @return the discovered information. - * @throws XMPPException if the operation failed for some reason. + * @throws XMPPErrorException if the operation failed for some reason. + * @throws NoResponseException if there was no response from the server. */ - public DiscoverInfo discoverInfo(String entityID, String node) throws XMPPException { + public DiscoverInfo discoverInfo(String entityID, String node) throws NoResponseException, XMPPErrorException { // Discover the entity's info DiscoverInfo disco = new DiscoverInfo(); disco.setType(IQ.Type.GET); @@ -555,9 +558,10 @@ public class ServiceDiscoveryManager extends Manager { * * @param entityID the address of the XMPP entity. * @return the discovered information. - * @throws XMPPException if the operation failed for some reason. + * @throws XMPPErrorException if the operation failed for some reason. + * @throws NoResponseException if there was no response from the server. */ - public DiscoverItems discoverItems(String entityID) throws XMPPException { + public DiscoverItems discoverItems(String entityID) throws NoResponseException, XMPPErrorException { return discoverItems(entityID, null); } @@ -569,9 +573,10 @@ public class ServiceDiscoveryManager extends Manager { * @param entityID the address of the XMPP entity. * @param node the optional attribute that supplements the 'jid' attribute. * @return the discovered items. - * @throws XMPPException if the operation failed for some reason. + * @throws XMPPErrorException if the operation failed for some reason. + * @throws NoResponseException if there was no response from the server. */ - public DiscoverItems discoverItems(String entityID, String node) throws XMPPException { + public DiscoverItems discoverItems(String entityID, String node) throws NoResponseException, XMPPErrorException { // Discover the entity's items DiscoverItems disco = new DiscoverItems(); disco.setType(IQ.Type.GET); @@ -590,9 +595,10 @@ public class ServiceDiscoveryManager extends Manager { * * @param entityID the address of the XMPP entity. * @return true if the server supports publishing of items. - * @throws XMPPException if the operation failed for some reason. + * @throws XMPPErrorException + * @throws NoResponseException */ - public boolean canPublishItems(String entityID) throws XMPPException { + public boolean canPublishItems(String entityID) throws NoResponseException, XMPPErrorException { DiscoverInfo info = discoverInfo(entityID); return canPublishItems(info); } @@ -618,10 +624,10 @@ public class ServiceDiscoveryManager extends Manager { * * @param entityID the address of the XMPP entity. * @param discoverItems the DiscoveryItems to publish. - * @throws XMPPException if the operation failed for some reason. + * @throws XMPPErrorException + * @throws NoResponseException */ - public void publishItems(String entityID, DiscoverItems discoverItems) - throws XMPPException { + public void publishItems(String entityID, DiscoverItems discoverItems) throws NoResponseException, XMPPErrorException { publishItems(entityID, null, discoverItems); } @@ -634,10 +640,11 @@ public class ServiceDiscoveryManager extends Manager { * @param entityID the address of the XMPP entity. * @param node the attribute that supplements the 'jid' attribute. * @param discoverItems the DiscoveryItems to publish. - * @throws XMPPException if the operation failed for some reason. + * @throws XMPPErrorException if the operation failed for some reason. + * @throws NoResponseException if there was no response from the server. */ - public void publishItems(String entityID, String node, DiscoverItems discoverItems) - throws XMPPException { + public void publishItems(String entityID, String node, DiscoverItems discoverItems) throws NoResponseException, XMPPErrorException + { discoverItems.setType(IQ.Type.SET); discoverItems.setTo(entityID); discoverItems.setNode(node); @@ -651,9 +658,10 @@ public class ServiceDiscoveryManager extends Manager { * @param jid the JID of the remote entity * @param feature * @return true if the entity supports the feature, false otherwise - * @throws XMPPException + * @throws XMPPErrorException + * @throws NoResponseException */ - public boolean supportsFeature(String jid, String feature) throws XMPPException { + public boolean supportsFeature(String jid, String feature) throws NoResponseException, XMPPErrorException { DiscoverInfo result = discoverInfo(jid); return result.containsFeature(feature); } diff --git a/extensions/src/main/java/org/jivesoftware/smackx/filetransfer/FaultTolerantNegotiator.java b/extensions/src/main/java/org/jivesoftware/smackx/filetransfer/FaultTolerantNegotiator.java index 3581e4313..1274afc57 100644 --- a/extensions/src/main/java/org/jivesoftware/smackx/filetransfer/FaultTolerantNegotiator.java +++ b/extensions/src/main/java/org/jivesoftware/smackx/filetransfer/FaultTolerantNegotiator.java @@ -17,8 +17,11 @@ package org.jivesoftware.smackx.filetransfer; import org.jivesoftware.smack.PacketCollector; +import org.jivesoftware.smack.SmackException; +import org.jivesoftware.smack.SmackException.NoResponseException; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.filter.OrFilter; import org.jivesoftware.smack.filter.PacketFilter; import org.jivesoftware.smack.packet.Packet; @@ -59,7 +62,7 @@ public class FaultTolerantNegotiator extends StreamNegotiator { return new OrFilter(primaryFilter, secondaryFilter); } - InputStream negotiateIncomingStream(Packet streamInitiation) throws XMPPException { + InputStream negotiateIncomingStream(Packet streamInitiation) { throw new UnsupportedOperationException("Negotiation only handled by create incoming " + "stream method."); } @@ -69,7 +72,7 @@ public class FaultTolerantNegotiator extends StreamNegotiator { "method"); } - public InputStream createIncomingStream(StreamInitiation initiation) throws XMPPException { + public InputStream createIncomingStream(StreamInitiation initiation) throws SmackException { PacketCollector collector = connection.createPacketCollector( getInitiationPacketFilter(initiation.getFrom(), initiation.getSessionID())); @@ -80,7 +83,7 @@ public class FaultTolerantNegotiator extends StreamNegotiator { = new ExecutorCompletionService(threadPoolExecutor); List> futures = new ArrayList>(); InputStream stream = null; - XMPPException exception = null; + SmackException exception = null; try { futures.add(service.submit(new NegotiatorService(collector))); futures.add(service.submit(new NegotiatorService(collector))); @@ -107,7 +110,7 @@ public class FaultTolerantNegotiator extends StreamNegotiator { /* Do Nothing */ } catch (ExecutionException e) { - exception = new XMPPException(e.getCause()); + exception = new SmackException(e.getCause()); } } } @@ -123,7 +126,7 @@ public class FaultTolerantNegotiator extends StreamNegotiator { throw exception; } else { - throw new XMPPException("File transfer negotiation failed."); + throw new SmackException("File transfer negotiation failed."); } } @@ -135,12 +138,12 @@ public class FaultTolerantNegotiator extends StreamNegotiator { } public OutputStream createOutgoingStream(String streamID, String initiator, String target) - throws XMPPException { + throws SmackException, XMPPException { OutputStream stream; try { stream = primaryNegotiator.createOutgoingStream(streamID, initiator, target); } - catch (XMPPException ex) { + catch (Exception ex) { stream = secondaryNegotiator.createOutgoingStream(streamID, initiator, target); } @@ -169,10 +172,10 @@ public class FaultTolerantNegotiator extends StreamNegotiator { this.collector = collector; } - public InputStream call() throws Exception { + public InputStream call() throws XMPPErrorException, InterruptedException, SmackException { Packet streamInitiation = collector.nextResult(); if (streamInitiation == null) { - throw new XMPPException("No response from remote client"); + throw new NoResponseException(); } StreamNegotiator negotiator = determineNegotiator(streamInitiation); return negotiator.negotiateIncomingStream(streamInitiation); diff --git a/extensions/src/main/java/org/jivesoftware/smackx/filetransfer/FileTransfer.java b/extensions/src/main/java/org/jivesoftware/smackx/filetransfer/FileTransfer.java index b67873f70..1ad5a838e 100644 --- a/extensions/src/main/java/org/jivesoftware/smackx/filetransfer/FileTransfer.java +++ b/extensions/src/main/java/org/jivesoftware/smackx/filetransfer/FileTransfer.java @@ -16,7 +16,7 @@ */ package org.jivesoftware.smackx.filetransfer; -import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.SmackException; import java.io.IOException; import java.io.InputStream; @@ -201,8 +201,8 @@ public abstract class FileTransfer { } } - protected void writeToStream(final InputStream in, final OutputStream out) - throws XMPPException + protected void writeToStream(final InputStream in, final OutputStream out) + throws SmackException { final byte[] b = new byte[BUFFER_SIZE]; int count = 0; @@ -213,7 +213,7 @@ public abstract class FileTransfer { try { out.write(b, 0, count); } catch (IOException e) { - throw new XMPPException("error writing to output stream", e); + throw new SmackException("error writing to output stream", e); } amountWritten += count; @@ -222,7 +222,7 @@ public abstract class FileTransfer { try { count = in.read(b); } catch (IOException e) { - throw new XMPPException("error reading from input stream", e); + throw new SmackException("error reading from input stream", e); } } while (count != -1 && !getStatus().equals(Status.cancelled)); diff --git a/extensions/src/main/java/org/jivesoftware/smackx/filetransfer/FileTransferNegotiator.java b/extensions/src/main/java/org/jivesoftware/smackx/filetransfer/FileTransferNegotiator.java index 8bd0005f3..561344d86 100644 --- a/extensions/src/main/java/org/jivesoftware/smackx/filetransfer/FileTransferNegotiator.java +++ b/extensions/src/main/java/org/jivesoftware/smackx/filetransfer/FileTransferNegotiator.java @@ -30,7 +30,7 @@ import java.util.concurrent.ConcurrentHashMap; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.ConnectionListener; import org.jivesoftware.smack.PacketCollector; -import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.Packet; import org.jivesoftware.smack.packet.XMPPError; @@ -249,11 +249,11 @@ public class FileTransferNegotiator { * * @param request The related file transfer request. * @return The file transfer object that handles the transfer - * @throws XMPPException If there are either no stream methods contained in the packet, or + * @throws XMPPErrorException If there are either no stream methods contained in the packet, or * there is not an appropriate stream method. */ public StreamNegotiator selectStreamNegotiator( - FileTransferRequest request) throws XMPPException { + FileTransferRequest request) throws XMPPErrorException { StreamInitiation si = request.getStreamInitiation(); FormField streamMethodField = getStreamMethodField(si .getFeatureNegotiationForm()); @@ -265,7 +265,7 @@ public class FileTransferNegotiator { IQ.Type.ERROR); iqPacket.setError(error); connection.sendPacket(iqPacket); - throw new XMPPException(errorMessage, error); + throw new XMPPErrorException(errorMessage, error); } // select the appropriate protocol @@ -274,7 +274,7 @@ public class FileTransferNegotiator { try { selectedStreamNegotiator = getNegotiator(streamMethodField); } - catch (XMPPException e) { + catch (XMPPErrorException e) { IQ iqPacket = createIQ(si.getPacketID(), si.getFrom(), si.getTo(), IQ.Type.ERROR); iqPacket.setError(e.getXMPPError()); @@ -300,7 +300,7 @@ public class FileTransferNegotiator { } private StreamNegotiator getNegotiator(final FormField field) - throws XMPPException { + throws XMPPErrorException { String variable; boolean isByteStream = false; boolean isIBB = false; @@ -317,7 +317,7 @@ public class FileTransferNegotiator { if (!isByteStream && !isIBB) { XMPPError error = new XMPPError(XMPPError.Condition.bad_request, "No acceptable transfer mechanism"); - throw new XMPPException(error.getMessage(), error); + throw new XMPPErrorException(error); } //if (isByteStream && isIBB && field.getType().equals(FormField.TYPE_LIST_MULTI)) { @@ -389,11 +389,11 @@ public class FileTransferNegotiator { * @param responseTimeout The amount of time, in milliseconds, to wait for the remote * user to respond. If they do not respond in time, this * @return Returns the stream negotiator selected by the peer. - * @throws XMPPException Thrown if there is an error negotiating the file transfer. + * @throws XMPPErrorException Thrown if there is an error negotiating the file transfer. */ public StreamNegotiator negotiateOutgoingTransfer(final String userID, final String streamID, final String fileName, final long size, - final String desc, int responseTimeout) throws XMPPException { + final String desc, int responseTimeout) throws XMPPErrorException { StreamInitiation si = new StreamInitiation(); si.setSessionID(streamID); si.setMimeType(URLConnection.guessContentTypeFromName(fileName)); @@ -420,11 +420,8 @@ public class FileTransferNegotiator { .getFeatureNegotiationForm())); } - else if (iqResponse.getType().equals(IQ.Type.ERROR)) { - throw new XMPPException(iqResponse.getError()); - } else { - throw new XMPPException("File transfer response unreadable"); + throw new XMPPErrorException(iqResponse.getError()); } } else { @@ -433,7 +430,7 @@ public class FileTransferNegotiator { } private StreamNegotiator getOutgoingNegotiator(final FormField field) - throws XMPPException { + throws XMPPErrorException { String variable; boolean isByteStream = false; boolean isIBB = false; @@ -450,7 +447,7 @@ public class FileTransferNegotiator { if (!isByteStream && !isIBB) { XMPPError error = new XMPPError(XMPPError.Condition.bad_request, "No acceptable transfer mechanism"); - throw new XMPPException(error.getMessage(), error); + throw new XMPPErrorException(error); } if (isByteStream && isIBB) { diff --git a/extensions/src/main/java/org/jivesoftware/smackx/filetransfer/IBBTransferNegotiator.java b/extensions/src/main/java/org/jivesoftware/smackx/filetransfer/IBBTransferNegotiator.java index fb938a2ce..d54d3f5ba 100644 --- a/extensions/src/main/java/org/jivesoftware/smackx/filetransfer/IBBTransferNegotiator.java +++ b/extensions/src/main/java/org/jivesoftware/smackx/filetransfer/IBBTransferNegotiator.java @@ -19,8 +19,9 @@ package org.jivesoftware.smackx.filetransfer; import java.io.InputStream; import java.io.OutputStream; +import org.jivesoftware.smack.SmackException.NoResponseException; import org.jivesoftware.smack.XMPPConnection; -import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.filter.AndFilter; import org.jivesoftware.smack.filter.FromMatchesFilter; import org.jivesoftware.smack.filter.PacketFilter; @@ -60,17 +61,17 @@ public class IBBTransferNegotiator extends StreamNegotiator { } public OutputStream createOutgoingStream(String streamID, String initiator, - String target) throws XMPPException { + String target) throws NoResponseException, XMPPErrorException { InBandBytestreamSession session = this.manager.establishSession(target, streamID); session.setCloseBothStreamsEnabled(true); return session.getOutputStream(); } public InputStream createIncomingStream(StreamInitiation initiation) - throws XMPPException { + throws NoResponseException, XMPPErrorException { /* - * In-Band Bytestream initiation listener must ignore next in-band - * bytestream request with given session ID + * In-Band Bytestream initiation listener must ignore next in-band bytestream request with + * given session ID */ this.manager.ignoreBytestreamRequestOnce(initiation.getSessionID()); @@ -93,7 +94,7 @@ public class IBBTransferNegotiator extends StreamNegotiator { return new String[] { InBandBytestreamManager.NAMESPACE }; } - InputStream negotiateIncomingStream(Packet streamInitiation) throws XMPPException { + InputStream negotiateIncomingStream(Packet streamInitiation) { // build In-Band Bytestream request InBandBytestreamRequest request = new ByteStreamRequest(this.manager, (Open) streamInitiation); diff --git a/extensions/src/main/java/org/jivesoftware/smackx/filetransfer/IncomingFileTransfer.java b/extensions/src/main/java/org/jivesoftware/smackx/filetransfer/IncomingFileTransfer.java index e5b269433..1752f2a94 100644 --- a/extensions/src/main/java/org/jivesoftware/smackx/filetransfer/IncomingFileTransfer.java +++ b/extensions/src/main/java/org/jivesoftware/smackx/filetransfer/IncomingFileTransfer.java @@ -16,7 +16,8 @@ */ package org.jivesoftware.smackx.filetransfer; -import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.SmackException; +import org.jivesoftware.smack.XMPPException.XMPPErrorException; import java.io.*; import java.util.concurrent.*; @@ -58,10 +59,11 @@ public class IncomingFileTransfer extends FileTransfer { * the negotiated stream. * * @return The negotiated InputStream from which to read the data. - * @throws XMPPException If there is an error in the negotiation process an exception + * @throws SmackException + * @throws XMPPErrorException If there is an error in the negotiation process an exception * is thrown. */ - public InputStream recieveFile() throws XMPPException { + public InputStream recieveFile() throws SmackException, XMPPErrorException { if (inputStream != null) { throw new IllegalStateException("Transfer already negotiated!"); } @@ -69,7 +71,7 @@ public class IncomingFileTransfer extends FileTransfer { try { inputStream = negotiateStream(); } - catch (XMPPException e) { + catch (XMPPErrorException e) { setException(e); throw e; } @@ -78,32 +80,31 @@ public class IncomingFileTransfer extends FileTransfer { } /** - * This method negotitates the stream and then transfer's the file over the - * negotiated stream. The transfered file will be saved at the provided - * location. + * This method negotitates the stream and then transfer's the file over the negotiated stream. + * The transfered file will be saved at the provided location. *

- * This method will return immedialtly, file transfer progress can be - * monitored through several methods: + * This method will return immedialtly, file transfer progress can be monitored through several + * methods: *

*

    *
  • {@link FileTransfer#getStatus()} *
  • {@link FileTransfer#getProgress()} *
  • {@link FileTransfer#isDone()} *
- * + * * @param file The location to save the file. - * @throws XMPPException when the file transfer fails + * @throws SmackException when the file transfer fails * @throws IllegalArgumentException This exception is thrown when the the provided file is - * either null, or cannot be written to. + * either null, or cannot be written to. */ - public void recieveFile(final File file) throws XMPPException { + public void recieveFile(final File file) throws SmackException { if (file != null) { if (!file.exists()) { try { file.createNewFile(); } catch (IOException e) { - throw new XMPPException( + throw new SmackException( "Could not create file to write too", e); } } @@ -120,8 +121,9 @@ public class IncomingFileTransfer extends FileTransfer { try { inputStream = negotiateStream(); } - catch (XMPPException e) { - handleXMPPException(e); + catch (Exception e) { + setStatus(FileTransfer.Status.error); + setException(e); return; } @@ -131,7 +133,7 @@ public class IncomingFileTransfer extends FileTransfer { setStatus(Status.in_progress); writeToStream(inputStream, outputStream); } - catch (XMPPException e) { + catch (SmackException e) { setStatus(Status.error); setError(Error.stream); setException(e); @@ -166,12 +168,7 @@ public class IncomingFileTransfer extends FileTransfer { transferThread.start(); } - private void handleXMPPException(XMPPException e) { - setStatus(FileTransfer.Status.error); - setException(e); - } - - private InputStream negotiateStream() throws XMPPException { + private InputStream negotiateStream() throws SmackException, XMPPErrorException { setStatus(Status.negotiating_transfer); final StreamNegotiator streamNegotiator = negotiator .selectStreamNegotiator(recieveRequest); @@ -190,13 +187,13 @@ public class IncomingFileTransfer extends FileTransfer { inputStream = streamNegotiatorTask.get(15, TimeUnit.SECONDS); } catch (InterruptedException e) { - throw new XMPPException("Interruption while executing", e); + throw new SmackException("Interruption while executing", e); } catch (ExecutionException e) { - throw new XMPPException("Error in execution", e); + throw new SmackException("Error in execution", e); } catch (TimeoutException e) { - throw new XMPPException("Request timed out", e); + throw new SmackException("Request timed out", e); } finally { streamNegotiatorTask.cancel(true); diff --git a/extensions/src/main/java/org/jivesoftware/smackx/filetransfer/OutgoingFileTransfer.java b/extensions/src/main/java/org/jivesoftware/smackx/filetransfer/OutgoingFileTransfer.java index 407e163f2..aeab5810a 100644 --- a/extensions/src/main/java/org/jivesoftware/smackx/filetransfer/OutgoingFileTransfer.java +++ b/extensions/src/main/java/org/jivesoftware/smackx/filetransfer/OutgoingFileTransfer.java @@ -16,7 +16,10 @@ */ package org.jivesoftware.smackx.filetransfer; +import org.jivesoftware.smack.SmackException; +import org.jivesoftware.smack.SmackException.IllegalStateChangeException; import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.packet.XMPPError; import java.io.*; @@ -108,9 +111,10 @@ public class OutgoingFileTransfer extends FileTransfer { * @throws XMPPException * Thrown if an error occurs during the file transfer * negotiation process. + * @throws SmackException if there was no response from the server. */ public synchronized OutputStream sendFile(String fileName, long fileSize, - String description) throws XMPPException { + String description) throws XMPPException, SmackException { if (isDone() || outputStream != null) { throw new IllegalStateException( "The negotation process has already" @@ -119,7 +123,7 @@ public class OutgoingFileTransfer extends FileTransfer { try { setFileInfo(fileName, fileSize); this.outputStream = negotiateStream(fileName, fileSize, description); - } catch (XMPPException e) { + } catch (XMPPErrorException e) { handleXMPPException(e); throw e; } @@ -166,9 +170,12 @@ public class OutgoingFileTransfer extends FileTransfer { fileName, fileSize, description); progress.outputStreamEstablished(OutgoingFileTransfer.this.outputStream); } - catch (XMPPException e) { + catch (XMPPErrorException e) { handleXMPPException(e); } + catch (Exception e) { + setException(e); + } } }, "File Transfer Negotiation " + streamID); transferThread.start(); @@ -194,12 +201,12 @@ public class OutgoingFileTransfer extends FileTransfer { * * @param file the file to transfer to the remote entity. * @param description a description for the file to transfer. - * @throws XMPPException + * @throws SmackException * If there is an error during the negotiation process or the * sending of the file. */ public synchronized void sendFile(final File file, final String description) - throws XMPPException { + throws SmackException { checkTransferThread(); if (file == null || !file.exists() || !file.canRead()) { throw new IllegalArgumentException("Could not read file"); @@ -212,10 +219,13 @@ public class OutgoingFileTransfer extends FileTransfer { try { outputStream = negotiateStream(file.getName(), file .length(), description); - } catch (XMPPException e) { + } catch (XMPPErrorException e) { handleXMPPException(e); return; } + catch (Exception e) { + setException(e); + } if (outputStream == null) { return; } @@ -232,7 +242,7 @@ public class OutgoingFileTransfer extends FileTransfer { setStatus(FileTransfer.Status.error); setError(Error.bad_file); setException(e); - } catch (XMPPException e) { + } catch (SmackException e) { setStatus(FileTransfer.Status.error); setException(e); } finally { @@ -279,10 +289,13 @@ public class OutgoingFileTransfer extends FileTransfer { //Create packet filter try { outputStream = negotiateStream(fileName, fileSize, description); - } catch (XMPPException e) { + } catch (XMPPErrorException e) { handleXMPPException(e); return; } + catch (Exception e) { + setException(e); + } if (outputStream == null) { return; } @@ -292,7 +305,7 @@ public class OutgoingFileTransfer extends FileTransfer { } try { writeToStream(in, outputStream); - } catch (XMPPException e) { + } catch (SmackException e) { setStatus(FileTransfer.Status.error); setException(e); } finally { @@ -314,7 +327,7 @@ public class OutgoingFileTransfer extends FileTransfer { transferThread.start(); } - private void handleXMPPException(XMPPException e) { + private void handleXMPPException(XMPPErrorException e) { XMPPError error = e.getXMPPError(); if (error != null) { String condition = error.getCondition(); @@ -350,11 +363,11 @@ public class OutgoingFileTransfer extends FileTransfer { } private OutputStream negotiateStream(String fileName, long fileSize, - String description) throws XMPPException { + String description) throws SmackException, XMPPException { // Negotiate the file transfer profile if (!updateStatus(Status.initial, Status.negotiating_transfer)) { - throw new XMPPException("Illegal state change"); + throw new IllegalStateChangeException(); } StreamNegotiator streamNegotiator = negotiator.negotiateOutgoingTransfer( getPeer(), streamID, fileName, fileSize, description, @@ -368,13 +381,13 @@ public class OutgoingFileTransfer extends FileTransfer { // Negotiate the stream if (!updateStatus(Status.negotiating_transfer, Status.negotiating_stream)) { - throw new XMPPException("Illegal state change"); + throw new IllegalStateChangeException(); } outputStream = streamNegotiator.createOutgoingStream(streamID, initiator, getPeer()); if (!updateStatus(Status.negotiating_stream, Status.negotiated)) { - throw new XMPPException("Illegal state change"); + throw new IllegalStateChangeException(); } return outputStream; } diff --git a/extensions/src/main/java/org/jivesoftware/smackx/filetransfer/Socks5TransferNegotiator.java b/extensions/src/main/java/org/jivesoftware/smackx/filetransfer/Socks5TransferNegotiator.java index 32c80f0b9..8ce0998e2 100644 --- a/extensions/src/main/java/org/jivesoftware/smackx/filetransfer/Socks5TransferNegotiator.java +++ b/extensions/src/main/java/org/jivesoftware/smackx/filetransfer/Socks5TransferNegotiator.java @@ -21,8 +21,11 @@ import java.io.InputStream; import java.io.OutputStream; import java.io.PushbackInputStream; +import org.jivesoftware.smack.SmackException; +import org.jivesoftware.smack.SmackException.NoResponseException; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.filter.AndFilter; import org.jivesoftware.smack.filter.FromMatchesFilter; import org.jivesoftware.smack.filter.PacketFilter; @@ -54,22 +57,22 @@ public class Socks5TransferNegotiator extends StreamNegotiator { } @Override - public OutputStream createOutgoingStream(String streamID, String initiator, String target) - throws XMPPException { + public OutputStream createOutgoingStream(String streamID, String initiator, String target) throws NoResponseException, SmackException, XMPPException + { try { return this.manager.establishSession(target, streamID).getOutputStream(); } catch (IOException e) { - throw new XMPPException("error establishing SOCKS5 Bytestream", e); + throw new SmackException("error establishing SOCKS5 Bytestream", e); } catch (InterruptedException e) { - throw new XMPPException("error establishing SOCKS5 Bytestream", e); + throw new SmackException("error establishing SOCKS5 Bytestream", e); } } @Override - public InputStream createIncomingStream(StreamInitiation initiation) throws XMPPException, - InterruptedException { + public InputStream createIncomingStream(StreamInitiation initiation) throws XMPPErrorException, + InterruptedException, SmackException { /* * SOCKS5 initiation listener must ignore next SOCKS5 Bytestream request with given session * ID @@ -98,8 +101,8 @@ public class Socks5TransferNegotiator extends StreamNegotiator { } @Override - InputStream negotiateIncomingStream(Packet streamInitiation) throws XMPPException, - InterruptedException { + InputStream negotiateIncomingStream(Packet streamInitiation) throws InterruptedException, + SmackException, XMPPErrorException { // build SOCKS5 Bytestream request Socks5BytestreamRequest request = new ByteStreamRequest(this.manager, (Bytestream) streamInitiation); @@ -115,7 +118,7 @@ public class Socks5TransferNegotiator extends StreamNegotiator { return stream; } catch (IOException e) { - throw new XMPPException("Error establishing input stream", e); + throw new SmackException("Error establishing input stream", e); } } diff --git a/extensions/src/main/java/org/jivesoftware/smackx/filetransfer/StreamNegotiator.java b/extensions/src/main/java/org/jivesoftware/smackx/filetransfer/StreamNegotiator.java index 72fd4c603..728bca740 100644 --- a/extensions/src/main/java/org/jivesoftware/smackx/filetransfer/StreamNegotiator.java +++ b/extensions/src/main/java/org/jivesoftware/smackx/filetransfer/StreamNegotiator.java @@ -17,8 +17,11 @@ package org.jivesoftware.smackx.filetransfer; import org.jivesoftware.smack.PacketCollector; +import org.jivesoftware.smack.SmackException; +import org.jivesoftware.smack.SmackException.NoResponseException; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.filter.PacketFilter; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.Packet; @@ -77,7 +80,7 @@ public abstract class StreamNegotiator { return iq; } - Packet initiateIncomingStream(XMPPConnection connection, StreamInitiation initiation) throws XMPPException { + Packet initiateIncomingStream(XMPPConnection connection, StreamInitiation initiation) throws NoResponseException, XMPPErrorException { StreamInitiation response = createInitiationAccept(initiation, getNamespaces()); @@ -86,11 +89,7 @@ public abstract class StreamNegotiator { .createPacketCollector(getInitiationPacketFilter(initiation.getFrom(), initiation.getSessionID())); connection.sendPacket(response); - Packet streamMethodInitiation = collector.nextResult(); - collector.cancel(); - if (streamMethodInitiation == null) { - throw new XMPPException("No response from file transfer initiator"); - } + Packet streamMethodInitiation = collector.nextResultOrThrow(); return streamMethodInitiation; } @@ -107,8 +106,8 @@ public abstract class StreamNegotiator { public abstract PacketFilter getInitiationPacketFilter(String from, String streamID); - abstract InputStream negotiateIncomingStream(Packet streamInitiation) throws XMPPException, - InterruptedException; + abstract InputStream negotiateIncomingStream(Packet streamInitiation) throws XMPPErrorException, + InterruptedException, NoResponseException, SmackException; /** * This method handles the file stream download negotiation process. The @@ -121,12 +120,13 @@ public abstract class StreamNegotiator { * @param initiation The initiation that triggered this download. * @return After the negotiation process is complete, the InputStream to * write a file to is returned. - * @throws XMPPException If an error occurs during this process an XMPPException is + * @throws XMPPErrorException If an error occurs during this process an XMPPException is * thrown. * @throws InterruptedException If thread is interrupted. + * @throws SmackException */ public abstract InputStream createIncomingStream(StreamInitiation initiation) - throws XMPPException, InterruptedException; + throws XMPPErrorException, InterruptedException, NoResponseException, SmackException; /** * This method handles the file upload stream negotiation process. The @@ -139,11 +139,13 @@ public abstract class StreamNegotiator { * @param target The fully-qualified JID of the target or receiver of the file * transfer. * @return The negotiated stream ready for data. - * @throws XMPPException If an error occurs during the negotiation process an + * @throws XMPPErrorException If an error occurs during the negotiation process an * exception will be thrown. + * @throws SmackException + * @throws XMPPException */ public abstract OutputStream createOutgoingStream(String streamID, - String initiator, String target) throws XMPPException; + String initiator, String target) throws XMPPErrorException, NoResponseException, SmackException, XMPPException; /** * Returns the XMPP namespace reserved for this particular type of file diff --git a/extensions/src/main/java/org/jivesoftware/smackx/iqlast/LastActivityManager.java b/extensions/src/main/java/org/jivesoftware/smackx/iqlast/LastActivityManager.java index fb664793f..512a80aa9 100644 --- a/extensions/src/main/java/org/jivesoftware/smackx/iqlast/LastActivityManager.java +++ b/extensions/src/main/java/org/jivesoftware/smackx/iqlast/LastActivityManager.java @@ -17,10 +17,13 @@ package org.jivesoftware.smackx.iqlast; +import org.jivesoftware.smack.SmackException; +import org.jivesoftware.smack.SmackException.NoResponseException; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.ConnectionCreationListener; import org.jivesoftware.smack.PacketListener; import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.filter.AndFilter; import org.jivesoftware.smack.filter.IQTypeFilter; import org.jivesoftware.smack.filter.PacketTypeFilter; @@ -189,10 +192,12 @@ public class LastActivityManager { * @param jid * the JID of the user. * @return the LastActivity packet of the jid. - * @throws XMPPException + * @throws XMPPErrorException * thrown if a server error has occured. + * @throws NoResponseException if there was no response from the server. */ - public static LastActivity getLastActivity(XMPPConnection con, String jid) throws XMPPException { + public static LastActivity getLastActivity(XMPPConnection con, String jid) + throws NoResponseException, XMPPErrorException { LastActivity activity = new LastActivity(); activity.setTo(jid); @@ -206,8 +211,9 @@ public class LastActivityManager { * @param connection the connection to be used * @param jid a JID to be tested for Last Activity support * @return true if Last Activity is supported, otherwise false + * @throws SmackException if there was no response from the server. */ - public static boolean isLastActivitySupported(XMPPConnection connection, String jid) { + public static boolean isLastActivitySupported(XMPPConnection connection, String jid) throws SmackException { try { DiscoverInfo result = ServiceDiscoveryManager.getInstanceFor(connection).discoverInfo(jid); diff --git a/extensions/src/main/java/org/jivesoftware/smackx/iqlast/packet/LastActivity.java b/extensions/src/main/java/org/jivesoftware/smackx/iqlast/packet/LastActivity.java index 081d044a9..c6478898f 100644 --- a/extensions/src/main/java/org/jivesoftware/smackx/iqlast/packet/LastActivity.java +++ b/extensions/src/main/java/org/jivesoftware/smackx/iqlast/packet/LastActivity.java @@ -19,11 +19,9 @@ package org.jivesoftware.smackx.iqlast.packet; import java.io.IOException; -import org.jivesoftware.smack.XMPPConnection; -import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.provider.IQProvider; -import org.jivesoftware.smack.util.StringUtils; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; @@ -98,9 +96,9 @@ public class LastActivity extends IQ { super(); } - public IQ parseIQ(XmlPullParser parser) throws XMPPException, XmlPullParserException { + public IQ parseIQ(XmlPullParser parser) throws SmackException, XmlPullParserException { if (parser.getEventType() != XmlPullParser.START_TAG) { - throw new XMPPException("Parser not in proper position, or bad XML."); + throw new SmackException("Parser not in proper position, or bad XML."); } LastActivity lastActivity = new LastActivity(); @@ -125,22 +123,4 @@ public class LastActivity extends IQ { return lastActivity; } } - - /** - * Retrieve the last activity of a particular jid. - * @param con the current XMPPConnection. - * @param jid the JID of the user. - * @return the LastActivity packet of the jid. - * @throws XMPPException thrown if a server error has occured. - * @deprecated This method only retreives the lapsed time since the last logout of a particular jid. - * Replaced by {@link org.jivesoftware.smackx.iqlast.LastActivityManager#getLastActivity(XMPPConnection, String) getLastActivity} - */ - public static LastActivity getLastActivity(XMPPConnection con, String jid) throws XMPPException { - LastActivity activity = new LastActivity(); - jid = StringUtils.parseBareAddress(jid); - activity.setTo(jid); - - LastActivity response = (LastActivity) con.createPacketCollectorAndSend(activity).nextResultOrThrow(); - return response; - } } diff --git a/extensions/src/main/java/org/jivesoftware/smackx/iqprivate/PrivateDataManager.java b/extensions/src/main/java/org/jivesoftware/smackx/iqprivate/PrivateDataManager.java index a0d79c32e..2ac51d131 100644 --- a/extensions/src/main/java/org/jivesoftware/smackx/iqprivate/PrivateDataManager.java +++ b/extensions/src/main/java/org/jivesoftware/smackx/iqprivate/PrivateDataManager.java @@ -17,8 +17,9 @@ package org.jivesoftware.smackx.iqprivate; +import org.jivesoftware.smack.SmackException.NoResponseException; import org.jivesoftware.smack.XMPPConnection; -import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.provider.IQProvider; import org.jivesoftware.smackx.iqprivate.packet.DefaultPrivateData; @@ -167,10 +168,10 @@ public class PrivateDataManager { * @param elementName the element name. * @param namespace the namespace. * @return the private data. - * @throws XMPPException if an error occurs getting the private data. + * @throws XMPPErrorException + * @throws NoResponseException */ - public PrivateData getPrivateData(final String elementName, final String namespace) - throws XMPPException + public PrivateData getPrivateData(final String elementName, final String namespace) throws NoResponseException, XMPPErrorException { // Create an IQ packet to get the private data. IQ privateDataGet = new IQ() { @@ -199,9 +200,10 @@ public class PrivateDataManager { * element name and namespace, then the new private data will overwrite the old value. * * @param privateData the private data. - * @throws XMPPException if setting the private data fails. + * @throws XMPPErrorException + * @throws NoResponseException */ - public void setPrivateData(final PrivateData privateData) throws XMPPException { + public void setPrivateData(final PrivateData privateData) throws NoResponseException, XMPPErrorException { // Create an IQ packet to set the private data. IQ privateDataSet = new IQ() { public String getChildElementXML() { diff --git a/extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java b/extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java index 564277519..1993453b0 100644 --- a/extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java +++ b/extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java @@ -40,8 +40,11 @@ import org.jivesoftware.smack.PacketCollector; import org.jivesoftware.smack.PacketInterceptor; import org.jivesoftware.smack.PacketListener; import org.jivesoftware.smack.SmackConfiguration; +import org.jivesoftware.smack.SmackException; +import org.jivesoftware.smack.SmackException.NoResponseException; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.filter.AndFilter; import org.jivesoftware.smack.filter.FromMatchesFilter; import org.jivesoftware.smack.filter.MessageTypeFilter; @@ -175,17 +178,13 @@ public class MultiUserChat { * @param connection the connection to use to perform the service discovery. * @param user the user to check. A fully qualified xmpp ID, e.g. jdoe@example.com. * @return a boolean indicating whether the specified user supports the MUC protocol. + * @throws XMPPErrorException + * @throws NoResponseException */ - public static boolean isServiceEnabled(XMPPConnection connection, String user) { - try { - DiscoverInfo result = - ServiceDiscoveryManager.getInstanceFor(connection).discoverInfo(user); - return result.containsFeature(discoNamespace); - } - catch (XMPPException e) { - LOGGER.log(Level.SEVERE, "Error checking user [" + user + "] for MUC support", e); - return false; - } + public static boolean isServiceEnabled(XMPPConnection connection, String user) + throws NoResponseException, XMPPErrorException { + return ServiceDiscoveryManager.getInstanceFor(connection).supportsFeature(user, + discoNamespace); } /** @@ -212,24 +211,20 @@ public class MultiUserChat { * @param connection the connection to use to perform the service discovery. * @param user the user to check. A fully qualified xmpp ID, e.g. jdoe@example.com. * @return an Iterator on the rooms where the requested user has joined. + * @throws XMPPErrorException + * @throws NoResponseException */ - public static Iterator getJoinedRooms(XMPPConnection connection, String user) { - try { - ArrayList answer = new ArrayList(); - // Send the disco packet to the user - DiscoverItems result = - ServiceDiscoveryManager.getInstanceFor(connection).discoverItems(user, discoNode); - // Collect the entityID for each returned item - for (Iterator items=result.getItems(); items.hasNext();) { - answer.add(items.next().getEntityID()); - } - return answer.iterator(); - } - catch (XMPPException e) { - LOGGER.log(Level.SEVERE, "Error getting joined rooms for user [" + user + "]", e); - // Return an iterator on an empty collection - return new ArrayList().iterator(); + public static Iterator getJoinedRooms(XMPPConnection connection, String user) + throws NoResponseException, XMPPErrorException { + ArrayList answer = new ArrayList(); + // Send the disco packet to the user + DiscoverItems result = ServiceDiscoveryManager.getInstanceFor(connection).discoverItems( + user, discoNode); + // Collect the entityID for each returned item + for (Iterator items = result.getItems(); items.hasNext();) { + answer.add(items.next().getEntityID()); } + return answer.iterator(); } /** @@ -240,10 +235,11 @@ public class MultiUserChat { * @param room the name of the room in the form "roomName@service" of which we want to discover * its information. * @return the discovered information of a given room without actually having to join the room. - * @throws XMPPException if an error occured while trying to discover information of a room. + * @throws XMPPErrorException + * @throws NoResponseException */ public static RoomInfo getRoomInfo(XMPPConnection connection, String room) - throws XMPPException { + throws NoResponseException, XMPPErrorException { DiscoverInfo info = ServiceDiscoveryManager.getInstanceFor(connection).discoverInfo(room); return new RoomInfo(info); } @@ -253,23 +249,18 @@ public class MultiUserChat { * * @param connection the XMPP connection to use for discovering Multi-User Chat services. * @return a collection with the XMPP addresses of the Multi-User Chat services. - * @throws XMPPException if an error occured while trying to discover MUC services. + * @throws XMPPErrorException + * @throws NoResponseException */ - public static Collection getServiceNames(XMPPConnection connection) throws XMPPException { + public static Collection getServiceNames(XMPPConnection connection) throws NoResponseException, XMPPErrorException { final List answer = new ArrayList(); ServiceDiscoveryManager discoManager = ServiceDiscoveryManager.getInstanceFor(connection); DiscoverItems items = discoManager.discoverItems(connection.getServiceName()); for (Iterator it = items.getItems(); it.hasNext();) { DiscoverItems.Item item = it.next(); - try { - DiscoverInfo info = discoManager.discoverInfo(item.getEntityID()); - if (info.containsFeature("http://jabber.org/protocol/muc")) { - answer.add(item.getEntityID()); - } - } - catch (XMPPException e) { - // Trouble finding info in some cases. This is a workaround for - // discovering info on remote servers. + DiscoverInfo info = discoManager.discoverInfo(item.getEntityID()); + if (info.containsFeature(discoNamespace)) { + answer.add(item.getEntityID()); } } return answer; @@ -283,10 +274,11 @@ public class MultiUserChat { * @param connection the XMPP connection to use for discovering hosted rooms by the MUC service. * @param serviceName the service that is hosting the rooms to discover. * @return a collection of HostedRooms. - * @throws XMPPException if an error occured while trying to discover the information. + * @throws XMPPErrorException + * @throws NoResponseException */ - public static Collection getHostedRooms(XMPPConnection connection, String serviceName) - throws XMPPException { + public static Collection getHostedRooms(XMPPConnection connection, + String serviceName) throws NoResponseException, XMPPErrorException { List answer = new ArrayList(); ServiceDiscoveryManager discoManager = ServiceDiscoveryManager.getInstanceFor(connection); DiscoverItems items = discoManager.discoverItems(serviceName); @@ -321,11 +313,13 @@ public class MultiUserChat { * will unlock the room. {@link #sendConfigurationForm(Form)} * * @param nickname the nickname to use. - * @throws XMPPException if the room couldn't be created for some reason + * @throws XMPPErrorException if the room couldn't be created for some reason * (e.g. room already exists; user already joined to an existant room or * 405 error if the user is not allowed to create the room) + * @throws NoResponseException if there was no response from the server. + * @throws SmackException If the creation failed because of a missing acknowledge from the server. */ - public synchronized void create(String nickname) throws XMPPException { + public synchronized void create(String nickname) throws NoResponseException, XMPPErrorException, SmackException { if (nickname == null || nickname.equals("")) { throw new IllegalArgumentException("Nickname must not be null or blank."); } @@ -371,7 +365,7 @@ public class MultiUserChat { } // We need to leave the room since it seems that the room already existed leave(); - throw new XMPPException("Creation failed - Missing acknowledge of room creation."); + throw new SmackException("Creation failed - Missing acknowledge of room creation."); } /** @@ -382,14 +376,16 @@ public class MultiUserChat { * joining the room, the room will decide the amount of history to send. * * @param nickname the nickname to use. - * @throws XMPPException if an error occurs joining the room. In particular, a + * @throws NoResponseException + * @throws XMPPErrorException if an error occurs joining the room. In particular, a * 401 error can occur if no password was provided and one is required; or a * 403 error can occur if the user is banned; or a * 404 error can occur if the room does not exist or is locked; or a * 407 error can occur if user is not on the member list; or a * 409 error can occur if someone is already in the group chat with the same nickname. + * @throws NoResponseException if there was no response from the server. */ - public void join(String nickname) throws XMPPException { + public void join(String nickname) throws NoResponseException, XMPPErrorException { join(nickname, null, null, SmackConfiguration.getDefaultPacketReplyTimeout()); } @@ -405,14 +401,15 @@ public class MultiUserChat { * * @param nickname the nickname to use. * @param password the password to use. - * @throws XMPPException if an error occurs joining the room. In particular, a + * @throws XMPPErrorException if an error occurs joining the room. In particular, a * 401 error can occur if no password was provided and one is required; or a * 403 error can occur if the user is banned; or a * 404 error can occur if the room does not exist or is locked; or a * 407 error can occur if user is not on the member list; or a * 409 error can occur if someone is already in the group chat with the same nickname. + * @throws SmackException if there was no response from the server. */ - public void join(String nickname, String password) throws XMPPException { + public void join(String nickname, String password) throws XMPPErrorException, SmackException { join(nickname, password, null, SmackConfiguration.getDefaultPacketReplyTimeout()); } @@ -434,19 +431,20 @@ public class MultiUserChat { * @param password the password to use. * @param history the amount of discussion history to receive while joining a room. * @param timeout the amount of time to wait for a reply from the MUC service(in milleseconds). - * @throws XMPPException if an error occurs joining the room. In particular, a + * @throws XMPPErrorException if an error occurs joining the room. In particular, a * 401 error can occur if no password was provided and one is required; or a * 403 error can occur if the user is banned; or a * 404 error can occur if the room does not exist or is locked; or a * 407 error can occur if user is not on the member list; or a * 409 error can occur if someone is already in the group chat with the same nickname. + * @throws NoResponseException if there was no response from the server. */ public synchronized void join( String nickname, String password, DiscussionHistory history, long timeout) - throws XMPPException { + throws XMPPErrorException, NoResponseException { if (nickname == null || nickname.equals("")) { throw new IllegalArgumentException("Nickname must not be null or blank."); } @@ -533,9 +531,10 @@ public class MultiUserChat { * * @return the Form that contains the fields to complete together with the instrucions or * null if no configuration is possible. - * @throws XMPPException if an error occurs asking the configuration form for the room. + * @throws XMPPErrorException if an error occurs asking the configuration form for the room. + * @throws NoResponseException if there was no response from the server. */ - public Form getConfigurationForm() throws XMPPException { + public Form getConfigurationForm() throws NoResponseException, XMPPErrorException { MUCOwner iq = new MUCOwner(); iq.setTo(room); iq.setType(IQ.Type.GET); @@ -550,9 +549,10 @@ public class MultiUserChat { * will create an instant room (will use default configuration). * * @param form the form with the new settings. - * @throws XMPPException if an error occurs setting the new rooms' configuration. + * @throws XMPPErrorException if an error occurs setting the new rooms' configuration. + * @throws NoResponseException if there was no response from the server. */ - public void sendConfigurationForm(Form form) throws XMPPException { + public void sendConfigurationForm(Form form) throws NoResponseException, XMPPErrorException { MUCOwner iq = new MUCOwner(); iq.setTo(room); iq.setType(IQ.Type.SET); @@ -572,10 +572,11 @@ public class MultiUserChat { * * @return the registration Form that contains the fields to complete together with the * instrucions or null if no registration is possible. - * @throws XMPPException if an error occurs asking the registration form for the room or a + * @throws XMPPErrorException if an error occurs asking the registration form for the room or a * 405 error if the user is not allowed to register with the room. + * @throws NoResponseException if there was no response from the server. */ - public Form getRegistrationForm() throws XMPPException { + public Form getRegistrationForm() throws NoResponseException, XMPPErrorException { Registration reg = new Registration(); reg.setType(IQ.Type.GET); reg.setTo(room); @@ -594,11 +595,12 @@ public class MultiUserChat { * it will return a "Service Unavailable" error to the user (error code 503). * * @param form the completed registration form. - * @throws XMPPException if an error occurs submitting the registration form. In particular, a + * @throws XMPPErrorException if an error occurs submitting the registration form. In particular, a * 409 error can occur if the desired room nickname is already reserved for that room; * or a 503 error can occur if the room does not support registration. + * @throws NoResponseException if there was no response from the server. */ - public void sendRegistrationForm(Form form) throws XMPPException { + public void sendRegistrationForm(Form form) throws NoResponseException, XMPPErrorException { Registration reg = new Registration(); reg.setType(IQ.Type.SET); reg.setTo(room); @@ -614,12 +616,13 @@ public class MultiUserChat { * * @param reason the reason for the room destruction. * @param alternateJID the JID of an alternate location. - * @throws XMPPException if an error occurs while trying to destroy the room. + * @throws XMPPErrorException if an error occurs while trying to destroy the room. * An error can occur which will be wrapped by an XMPPException -- * XMPP error code 403. The error code can be used to present more * appropiate error messages to end-users. + * @throws NoResponseException if there was no response from the server. */ - public void destroy(String reason, String alternateJID) throws XMPPException { + public void destroy(String reason, String alternateJID) throws NoResponseException, XMPPErrorException { MUCOwner iq = new MUCOwner(); iq.setTo(room); iq.setType(IQ.Type.SET); @@ -855,8 +858,9 @@ public class MultiUserChat { * to enter the room. * * @return the reserved room nickname or null if none. + * @throws SmackException if there was no response from the server. */ - public String getReservedNickname() { + public String getReservedNickname() throws SmackException { try { DiscoverInfo result = ServiceDiscoveryManager.getInstanceFor(connection).discoverInfo( @@ -894,9 +898,10 @@ public class MultiUserChat { * status code 303 indicates that the occupant is changing his/her nickname. * * @param nickname the new nickname within the room. - * @throws XMPPException if the new nickname is already in use by another occupant. + * @throws XMPPErrorException if the new nickname is already in use by another occupant. + * @throws NoResponseException if there was no response from the server. */ - public void changeNickname(String nickname) throws XMPPException { + public void changeNickname(String nickname) throws NoResponseException, XMPPErrorException { if (nickname == null || nickname.equals("")) { throw new IllegalArgumentException("Nickname must not be null or blank."); } @@ -974,14 +979,15 @@ public class MultiUserChat { * @param nickname the nickname of the participant or visitor to kick from the room * (e.g. "john"). * @param reason the reason why the participant or visitor is being kicked from the room. - * @throws XMPPException if an error occurs kicking the occupant. In particular, a + * @throws XMPPErrorException if an error occurs kicking the occupant. In particular, a * 405 error can occur if a moderator or a user with an affiliation of "owner" or "admin" * was intended to be kicked (i.e. Not Allowed error); or a * 403 error can occur if the occupant that intended to kick another occupant does * not have kicking privileges (i.e. Forbidden error); or a * 400 error can occur if the provided nickname is not present in the room. + * @throws NoResponseException if there was no response from the server. */ - public void kickParticipant(String nickname, String reason) throws XMPPException { + public void kickParticipant(String nickname, String reason) throws XMPPErrorException, NoResponseException { changeRole(nickname, "none", reason); } @@ -991,12 +997,13 @@ public class MultiUserChat { * is able to send messages to the room occupants. * * @param nicknames the nicknames of the visitors to grant voice in the room (e.g. "john"). - * @throws XMPPException if an error occurs granting voice to a visitor. In particular, a + * @throws XMPPErrorException if an error occurs granting voice to a visitor. In particular, a * 403 error can occur if the occupant that intended to grant voice is not * a moderator in this room (i.e. Forbidden error); or a * 400 error can occur if the provided nickname is not present in the room. + * @throws NoResponseException if there was no response from the server. */ - public void grantVoice(Collection nicknames) throws XMPPException { + public void grantVoice(Collection nicknames) throws XMPPErrorException, NoResponseException { changeRole(nicknames, "participant"); } @@ -1006,12 +1013,13 @@ public class MultiUserChat { * is able to send messages to the room occupants. * * @param nickname the nickname of the visitor to grant voice in the room (e.g. "john"). - * @throws XMPPException if an error occurs granting voice to a visitor. In particular, a + * @throws XMPPErrorException if an error occurs granting voice to a visitor. In particular, a * 403 error can occur if the occupant that intended to grant voice is not * a moderator in this room (i.e. Forbidden error); or a * 400 error can occur if the provided nickname is not present in the room. + * @throws NoResponseException if there was no response from the server. */ - public void grantVoice(String nickname) throws XMPPException { + public void grantVoice(String nickname) throws XMPPErrorException, NoResponseException { changeRole(nickname, "participant", null); } @@ -1021,12 +1029,13 @@ public class MultiUserChat { * is able to send messages to the room occupants. * * @param nicknames the nicknames of the participants to revoke voice (e.g. "john"). - * @throws XMPPException if an error occurs revoking voice from a participant. In particular, a + * @throws XMPPErrorException if an error occurs revoking voice from a participant. In particular, a * 405 error can occur if a moderator or a user with an affiliation of "owner" or "admin" * was tried to revoke his voice (i.e. Not Allowed error); or a * 400 error can occur if the provided nickname is not present in the room. + * @throws NoResponseException if there was no response from the server. */ - public void revokeVoice(Collection nicknames) throws XMPPException { + public void revokeVoice(Collection nicknames) throws XMPPErrorException, NoResponseException { changeRole(nicknames, "visitor"); } @@ -1036,12 +1045,13 @@ public class MultiUserChat { * is able to send messages to the room occupants. * * @param nickname the nickname of the participant to revoke voice (e.g. "john"). - * @throws XMPPException if an error occurs revoking voice from a participant. In particular, a + * @throws XMPPErrorException if an error occurs revoking voice from a participant. In particular, a * 405 error can occur if a moderator or a user with an affiliation of "owner" or "admin" * was tried to revoke his voice (i.e. Not Allowed error); or a * 400 error can occur if the provided nickname is not present in the room. + * @throws NoResponseException if there was no response from the server. */ - public void revokeVoice(String nickname) throws XMPPException { + public void revokeVoice(String nickname) throws XMPPErrorException, NoResponseException { changeRole(nickname, "visitor", null); } @@ -1053,11 +1063,12 @@ public class MultiUserChat { * XMPP user ID of the user who initiated the ban. * * @param jids the bare XMPP user IDs of the users to ban. - * @throws XMPPException if an error occurs banning a user. In particular, a + * @throws XMPPErrorException if an error occurs banning a user. In particular, a * 405 error can occur if a moderator or a user with an affiliation of "owner" or "admin" * was tried to be banned (i.e. Not Allowed error). + * @throws NoResponseException if there was no response from the server. */ - public void banUsers(Collection jids) throws XMPPException { + public void banUsers(Collection jids) throws XMPPErrorException, NoResponseException { changeAffiliationByAdmin(jids, "outcast"); } @@ -1070,11 +1081,12 @@ public class MultiUserChat { * * @param jid the bare XMPP user ID of the user to ban (e.g. "user@host.org"). * @param reason the optional reason why the user was banned. - * @throws XMPPException if an error occurs banning a user. In particular, a + * @throws XMPPErrorException if an error occurs banning a user. In particular, a * 405 error can occur if a moderator or a user with an affiliation of "owner" or "admin" * was tried to be banned (i.e. Not Allowed error). + * @throws NoResponseException if there was no response from the server. */ - public void banUser(String jid, String reason) throws XMPPException { + public void banUser(String jid, String reason) throws XMPPErrorException, NoResponseException { changeAffiliationByAdmin(jid, "outcast", reason); } @@ -1084,9 +1096,10 @@ public class MultiUserChat { * that a user cannot enter without being on the member list). * * @param jids the XMPP user IDs of the users to grant membership. - * @throws XMPPException if an error occurs granting membership to a user. + * @throws XMPPErrorException if an error occurs granting membership to a user. + * @throws NoResponseException if there was no response from the server. */ - public void grantMembership(Collection jids) throws XMPPException { + public void grantMembership(Collection jids) throws XMPPErrorException, NoResponseException { changeAffiliationByAdmin(jids, "member"); } @@ -1096,9 +1109,10 @@ public class MultiUserChat { * that a user cannot enter without being on the member list). * * @param jid the XMPP user ID of the user to grant membership (e.g. "user@host.org"). - * @throws XMPPException if an error occurs granting membership to a user. + * @throws XMPPErrorException if an error occurs granting membership to a user. + * @throws NoResponseException if there was no response from the server. */ - public void grantMembership(String jid) throws XMPPException { + public void grantMembership(String jid) throws XMPPErrorException, NoResponseException { changeAffiliationByAdmin(jid, "member", null); } @@ -1109,9 +1123,10 @@ public class MultiUserChat { * the room is of type members-only then the user will be removed from the room. * * @param jids the bare XMPP user IDs of the users to revoke membership. - * @throws XMPPException if an error occurs revoking membership to a user. + * @throws XMPPErrorException if an error occurs revoking membership to a user. + * @throws NoResponseException if there was no response from the server. */ - public void revokeMembership(Collection jids) throws XMPPException { + public void revokeMembership(Collection jids) throws XMPPErrorException, NoResponseException { changeAffiliationByAdmin(jids, "none"); } @@ -1122,9 +1137,10 @@ public class MultiUserChat { * the room is of type members-only then the user will be removed from the room. * * @param jid the bare XMPP user ID of the user to revoke membership (e.g. "user@host.org"). - * @throws XMPPException if an error occurs revoking membership to a user. + * @throws XMPPErrorException if an error occurs revoking membership to a user. + * @throws NoResponseException if there was no response from the server. */ - public void revokeMembership(String jid) throws XMPPException { + public void revokeMembership(String jid) throws XMPPErrorException, NoResponseException { changeAffiliationByAdmin(jid, "none", null); } @@ -1134,9 +1150,10 @@ public class MultiUserChat { * other users, modify room's subject plus all the partcipants privileges. * * @param nicknames the nicknames of the occupants to grant moderator privileges. - * @throws XMPPException if an error occurs granting moderator privileges to a user. + * @throws XMPPErrorException if an error occurs granting moderator privileges to a user. + * @throws NoResponseException if there was no response from the server. */ - public void grantModerator(Collection nicknames) throws XMPPException { + public void grantModerator(Collection nicknames) throws XMPPErrorException, NoResponseException { changeRole(nicknames, "moderator"); } @@ -1146,9 +1163,10 @@ public class MultiUserChat { * other users, modify room's subject plus all the partcipants privileges. * * @param nickname the nickname of the occupant to grant moderator privileges. - * @throws XMPPException if an error occurs granting moderator privileges to a user. + * @throws XMPPErrorException if an error occurs granting moderator privileges to a user. + * @throws NoResponseException if there was no response from the server. */ - public void grantModerator(String nickname) throws XMPPException { + public void grantModerator(String nickname) throws XMPPErrorException, NoResponseException { changeRole(nickname, "moderator", null); } @@ -1159,9 +1177,10 @@ public class MultiUserChat { * not allowed to revoke moderator privileges from other room administrators or owners. * * @param nicknames the nicknames of the occupants to revoke moderator privileges. - * @throws XMPPException if an error occurs revoking moderator privileges from a user. + * @throws XMPPErrorException if an error occurs revoking moderator privileges from a user. + * @throws NoResponseException if there was no response from the server. */ - public void revokeModerator(Collection nicknames) throws XMPPException { + public void revokeModerator(Collection nicknames) throws XMPPErrorException, NoResponseException { changeRole(nicknames, "participant"); } @@ -1172,9 +1191,10 @@ public class MultiUserChat { * not allowed to revoke moderator privileges from other room administrators or owners. * * @param nickname the nickname of the occupant to revoke moderator privileges. - * @throws XMPPException if an error occurs revoking moderator privileges from a user. + * @throws XMPPErrorException if an error occurs revoking moderator privileges from a user. + * @throws NoResponseException if there was no response from the server. */ - public void revokeModerator(String nickname) throws XMPPException { + public void revokeModerator(String nickname) throws XMPPErrorException, NoResponseException { changeRole(nickname, "participant", null); } @@ -1185,9 +1205,10 @@ public class MultiUserChat { * functions. * * @param jids the collection of bare XMPP user IDs of the users to grant ownership. - * @throws XMPPException if an error occurs granting ownership privileges to a user. + * @throws XMPPErrorException if an error occurs granting ownership privileges to a user. + * @throws NoResponseException if there was no response from the server. */ - public void grantOwnership(Collection jids) throws XMPPException { + public void grantOwnership(Collection jids) throws XMPPErrorException, NoResponseException { changeAffiliationByAdmin(jids, "owner"); } @@ -1198,9 +1219,10 @@ public class MultiUserChat { * functions. * * @param jid the bare XMPP user ID of the user to grant ownership (e.g. "user@host.org"). - * @throws XMPPException if an error occurs granting ownership privileges to a user. + * @throws XMPPErrorException if an error occurs granting ownership privileges to a user. + * @throws NoResponseException if there was no response from the server. */ - public void grantOwnership(String jid) throws XMPPException { + public void grantOwnership(String jid) throws XMPPErrorException, NoResponseException { changeAffiliationByAdmin(jid, "owner", null); } @@ -1210,9 +1232,10 @@ public class MultiUserChat { * Some room implementations will not allow to grant ownership privileges to other users. * * @param jids the bare XMPP user IDs of the users to revoke ownership. - * @throws XMPPException if an error occurs revoking ownership privileges from a user. + * @throws XMPPErrorException if an error occurs revoking ownership privileges from a user. + * @throws NoResponseException if there was no response from the server. */ - public void revokeOwnership(Collection jids) throws XMPPException { + public void revokeOwnership(Collection jids) throws XMPPErrorException, NoResponseException { changeAffiliationByAdmin(jids, "admin"); } @@ -1222,9 +1245,10 @@ public class MultiUserChat { * Some room implementations will not allow to grant ownership privileges to other users. * * @param jid the bare XMPP user ID of the user to revoke ownership (e.g. "user@host.org"). - * @throws XMPPException if an error occurs revoking ownership privileges from a user. + * @throws XMPPErrorException if an error occurs revoking ownership privileges from a user. + * @throws NoResponseException if there was no response from the server. */ - public void revokeOwnership(String jid) throws XMPPException { + public void revokeOwnership(String jid) throws XMPPErrorException, NoResponseException { changeAffiliationByAdmin(jid, "admin", null); } @@ -1234,9 +1258,10 @@ public class MultiUserChat { * administrative functions such as banning users and edit moderator list. * * @param jids the bare XMPP user IDs of the users to grant administrator privileges. - * @throws XMPPException if an error occurs granting administrator privileges to a user. + * @throws XMPPErrorException if an error occurs granting administrator privileges to a user. + * @throws NoResponseException if there was no response from the server. */ - public void grantAdmin(Collection jids) throws XMPPException { + public void grantAdmin(Collection jids) throws XMPPErrorException, NoResponseException { changeAffiliationByOwner(jids, "admin"); } @@ -1247,9 +1272,10 @@ public class MultiUserChat { * * @param jid the bare XMPP user ID of the user to grant administrator privileges * (e.g. "user@host.org"). - * @throws XMPPException if an error occurs granting administrator privileges to a user. + * @throws XMPPErrorException if an error occurs granting administrator privileges to a user. + * @throws NoResponseException if there was no response from the server. */ - public void grantAdmin(String jid) throws XMPPException { + public void grantAdmin(String jid) throws XMPPErrorException, NoResponseException { changeAffiliationByOwner(jid, "admin"); } @@ -1259,9 +1285,10 @@ public class MultiUserChat { * a member or unaffiliated user. * * @param jids the bare XMPP user IDs of the user to revoke administrator privileges. - * @throws XMPPException if an error occurs revoking administrator privileges from a user. + * @throws XMPPErrorException if an error occurs revoking administrator privileges from a user. + * @throws NoResponseException if there was no response from the server. */ - public void revokeAdmin(Collection jids) throws XMPPException { + public void revokeAdmin(Collection jids) throws XMPPErrorException, NoResponseException { changeAffiliationByOwner(jids, "member"); } @@ -1272,13 +1299,15 @@ public class MultiUserChat { * * @param jid the bare XMPP user ID of the user to revoke administrator privileges * (e.g. "user@host.org"). - * @throws XMPPException if an error occurs revoking administrator privileges from a user. + * @throws XMPPErrorException if an error occurs revoking administrator privileges from a user. + * @throws NoResponseException if there was no response from the server. */ - public void revokeAdmin(String jid) throws XMPPException { + public void revokeAdmin(String jid) throws XMPPErrorException, NoResponseException { changeAffiliationByOwner(jid, "member"); } - private void changeAffiliationByOwner(String jid, String affiliation) throws XMPPException { + private void changeAffiliationByOwner(String jid, String affiliation) + throws XMPPErrorException, NoResponseException { MUCOwner iq = new MUCOwner(); iq.setTo(room); iq.setType(IQ.Type.SET); @@ -1291,7 +1320,7 @@ public class MultiUserChat { } private void changeAffiliationByOwner(Collection jids, String affiliation) - throws XMPPException { + throws NoResponseException, XMPPErrorException { MUCOwner iq = new MUCOwner(); iq.setTo(room); iq.setType(IQ.Type.SET); @@ -1311,10 +1340,11 @@ public class MultiUserChat { * @param jid * @param affiliation * @param reason the reason for the affiliation change (optional) - * @throws XMPPException + * @throws XMPPErrorException + * @throws NoResponseException */ - private void changeAffiliationByAdmin(String jid, String affiliation, String reason) - throws XMPPException { + private void changeAffiliationByAdmin(String jid, String affiliation, String reason) throws NoResponseException, XMPPErrorException + { MUCAdmin iq = new MUCAdmin(); iq.setTo(room); iq.setType(IQ.Type.SET); @@ -1328,7 +1358,7 @@ public class MultiUserChat { } private void changeAffiliationByAdmin(Collection jids, String affiliation) - throws XMPPException { + throws NoResponseException, XMPPErrorException { MUCAdmin iq = new MUCAdmin(); iq.setTo(room); iq.setType(IQ.Type.SET); @@ -1342,7 +1372,7 @@ public class MultiUserChat { connection.createPacketCollectorAndSend(iq).nextResultOrThrow(); } - private void changeRole(String nickname, String role, String reason) throws XMPPException { + private void changeRole(String nickname, String role, String reason) throws NoResponseException, XMPPErrorException { MUCAdmin iq = new MUCAdmin(); iq.setTo(room); iq.setType(IQ.Type.SET); @@ -1355,7 +1385,7 @@ public class MultiUserChat { connection.createPacketCollectorAndSend(iq).nextResultOrThrow(); } - private void changeRole(Collection nicknames, String role) throws XMPPException { + private void changeRole(Collection nicknames, String role) throws NoResponseException, XMPPErrorException { MUCAdmin iq = new MUCAdmin(); iq.setTo(room); iq.setType(IQ.Type.SET); @@ -1458,10 +1488,10 @@ public class MultiUserChat { * Returns a collection of Affiliate with the room owners. * * @return a collection of Affiliate with the room owners. - * @throws XMPPException if an error occured while performing the request to the server or you - * don't have enough privileges to get this information. + * @throws XMPPErrorException if you don't have enough privileges to get this information. + * @throws NoResponseException if there was no response from the server. */ - public Collection getOwners() throws XMPPException { + public Collection getOwners() throws NoResponseException, XMPPErrorException { return getAffiliatesByAdmin("owner"); } @@ -1469,10 +1499,10 @@ public class MultiUserChat { * Returns a collection of Affiliate with the room administrators. * * @return a collection of Affiliate with the room administrators. - * @throws XMPPException if an error occured while performing the request to the server or you - * don't have enough privileges to get this information. + * @throws XMPPErrorException if you don't have enough privileges to get this information. + * @throws NoResponseException if there was no response from the server. */ - public Collection getAdmins() throws XMPPException { + public Collection getAdmins() throws NoResponseException, XMPPErrorException { return getAffiliatesByAdmin("admin"); } @@ -1480,10 +1510,10 @@ public class MultiUserChat { * Returns a collection of Affiliate with the room members. * * @return a collection of Affiliate with the room members. - * @throws XMPPException if an error occured while performing the request to the server or you - * don't have enough privileges to get this information. + * @throws XMPPErrorException if you don't have enough privileges to get this information. + * @throws NoResponseException if there was no response from the server. */ - public Collection getMembers() throws XMPPException { + public Collection getMembers() throws NoResponseException, XMPPErrorException { return getAffiliatesByAdmin("member"); } @@ -1491,10 +1521,10 @@ public class MultiUserChat { * Returns a collection of Affiliate with the room outcasts. * * @return a collection of Affiliate with the room outcasts. - * @throws XMPPException if an error occured while performing the request to the server or you - * don't have enough privileges to get this information. + * @throws XMPPErrorException if you don't have enough privileges to get this information. + * @throws NoResponseException if there was no response from the server. */ - public Collection getOutcasts() throws XMPPException { + public Collection getOutcasts() throws NoResponseException, XMPPErrorException { return getAffiliatesByAdmin("outcast"); } @@ -1504,10 +1534,10 @@ public class MultiUserChat { * * @param affiliation the affiliation of the users in the room. * @return a collection of Affiliate that have the specified room affiliation. - * @throws XMPPException if an error occured while performing the request to the server or you - * don't have enough privileges to get this information. + * @throws XMPPErrorException if you don't have enough privileges to get this information. + * @throws NoResponseException if there was no response from the server. */ - private Collection getAffiliatesByAdmin(String affiliation) throws XMPPException { + private Collection getAffiliatesByAdmin(String affiliation) throws NoResponseException, XMPPErrorException { MUCAdmin iq = new MUCAdmin(); iq.setTo(room); iq.setType(IQ.Type.GET); @@ -1529,21 +1559,21 @@ public class MultiUserChat { * Returns a collection of Occupant with the room moderators. * * @return a collection of Occupant with the room moderators. - * @throws XMPPException if an error occured while performing the request to the server or you - * don't have enough privileges to get this information. + * @throws XMPPErrorException if you don't have enough privileges to get this information. + * @throws NoResponseException if there was no response from the server. */ - public Collection getModerators() throws XMPPException { + public Collection getModerators() throws NoResponseException, XMPPErrorException { return getOccupants("moderator"); } /** * Returns a collection of Occupant with the room participants. - * + * * @return a collection of Occupant with the room participants. - * @throws XMPPException if an error occured while performing the request to the server or you - * don't have enough privileges to get this information. + * @throws XMPPErrorException if you don't have enough privileges to get this information. + * @throws NoResponseException if there was no response from the server. */ - public Collection getParticipants() throws XMPPException { + public Collection getParticipants() throws NoResponseException, XMPPErrorException { return getOccupants("participant"); } @@ -1552,10 +1582,11 @@ public class MultiUserChat { * * @param role the role of the occupant in the room. * @return a collection of Occupant that have the specified room role. - * @throws XMPPException if an error occured while performing the request to the server or you + * @throws XMPPErrorException if an error occured while performing the request to the server or you * don't have enough privileges to get this information. + * @throws NoResponseException if there was no response from the server. */ - private Collection getOccupants(String role) throws XMPPException { + private Collection getOccupants(String role) throws NoResponseException, XMPPErrorException { MUCAdmin iq = new MUCAdmin(); iq.setTo(room); iq.setType(IQ.Type.GET); @@ -1689,10 +1720,11 @@ public class MultiUserChat { * allow a mere participant or even a visitor to change the subject. * * @param subject the new room's subject to set. - * @throws XMPPException if someone without appropriate privileges attempts to change the + * @throws XMPPErrorException if someone without appropriate privileges attempts to change the * room subject will throw an error with code 403 (i.e. Forbidden) + * @throws NoResponseException if there was no response from the server. */ - public void changeSubject(final String subject) throws XMPPException { + public void changeSubject(final String subject) throws NoResponseException, XMPPErrorException { Message message = new Message(room, Message.Type.groupchat); message.setSubject(subject); // Wait for an error or confirmation message back from the server. diff --git a/extensions/src/main/java/org/jivesoftware/smackx/offline/OfflineMessageManager.java b/extensions/src/main/java/org/jivesoftware/smackx/offline/OfflineMessageManager.java index d6aab29b3..be97e0104 100644 --- a/extensions/src/main/java/org/jivesoftware/smackx/offline/OfflineMessageManager.java +++ b/extensions/src/main/java/org/jivesoftware/smackx/offline/OfflineMessageManager.java @@ -19,8 +19,9 @@ package org.jivesoftware.smackx.offline; import org.jivesoftware.smack.PacketCollector; import org.jivesoftware.smack.SmackConfiguration; +import org.jivesoftware.smack.SmackException.NoResponseException; import org.jivesoftware.smack.XMPPConnection; -import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.filter.AndFilter; import org.jivesoftware.smack.filter.PacketExtensionFilter; import org.jivesoftware.smack.filter.PacketFilter; @@ -75,21 +76,22 @@ public class OfflineMessageManager { * messages, get specific messages, delete specific messages, etc. * * @return a boolean indicating if the server supports Flexible Offline Message Retrieval. - * @throws XMPPException If the user is not allowed to make this request. + * @throws XMPPErrorException If the user is not allowed to make this request. + * @throws NoResponseException if there was no response from the server. */ - public boolean supportsFlexibleRetrieval() throws XMPPException { - DiscoverInfo info = ServiceDiscoveryManager.getInstanceFor(connection).discoverInfo(null); - return info.containsFeature(namespace); + public boolean supportsFlexibleRetrieval() throws NoResponseException, XMPPErrorException { + return ServiceDiscoveryManager.getInstanceFor(connection).supportsFeature(connection.getServiceName(), namespace); } /** * Returns the number of offline messages for the user of the connection. * * @return the number of offline messages for the user of the connection. - * @throws XMPPException If the user is not allowed to make this request or the server does + * @throws XMPPErrorException If the user is not allowed to make this request or the server does * not support offline message retrieval. + * @throws NoResponseException if there was no response from the server. */ - public int getMessageCount() throws XMPPException { + public int getMessageCount() throws NoResponseException, XMPPErrorException { DiscoverInfo info = ServiceDiscoveryManager.getInstanceFor(connection).discoverInfo(null, namespace); Form extendedInfo = Form.getFormFrom(info); @@ -107,10 +109,11 @@ public class OfflineMessageManager { * * @return an iterator on OfflineMessageHeader that keep information about the offline * message. - * @throws XMPPException If the user is not allowed to make this request or the server does + * @throws XMPPErrorException If the user is not allowed to make this request or the server does * not support offline message retrieval. + * @throws NoResponseException if there was no response from the server. */ - public Iterator getHeaders() throws XMPPException { + public Iterator getHeaders() throws NoResponseException, XMPPErrorException { List answer = new ArrayList(); DiscoverItems items = ServiceDiscoveryManager.getInstanceFor(connection).discoverItems( null, namespace); @@ -130,10 +133,11 @@ public class OfflineMessageManager { * @param nodes the list of stamps that uniquely identifies offline message. * @return an Iterator with the offline Messages that were received as part of * this request. - * @throws XMPPException If the user is not allowed to make this request or the server does + * @throws XMPPErrorException If the user is not allowed to make this request or the server does * not support offline message retrieval. + * @throws NoResponseException if there was no response from the server. */ - public Iterator getMessages(final List nodes) throws XMPPException { + public Iterator getMessages(final List nodes) throws NoResponseException, XMPPErrorException { List messages = new ArrayList(); OfflineMessageRequest request = new OfflineMessageRequest(); for (String node : nodes) { @@ -170,10 +174,11 @@ public class OfflineMessageManager { * to delete the messages. * * @return an Iterator with all the offline Messages of the user. - * @throws XMPPException If the user is not allowed to make this request or the server does + * @throws XMPPErrorException If the user is not allowed to make this request or the server does * not support offline message retrieval. + * @throws NoResponseException if there was no response from the server. */ - public Iterator getMessages() throws XMPPException { + public Iterator getMessages() throws NoResponseException, XMPPErrorException { List messages = new ArrayList(); OfflineMessageRequest request = new OfflineMessageRequest(); request.setFetch(true); @@ -198,10 +203,11 @@ public class OfflineMessageManager { * stamps that uniquely identifies the offline messages to delete. * * @param nodes the list of stamps that uniquely identifies offline message. - * @throws XMPPException If the user is not allowed to make this request or the server does + * @throws XMPPErrorException If the user is not allowed to make this request or the server does * not support offline message retrieval. + * @throws NoResponseException if there was no response from the server. */ - public void deleteMessages(List nodes) throws XMPPException { + public void deleteMessages(List nodes) throws NoResponseException, XMPPErrorException { OfflineMessageRequest request = new OfflineMessageRequest(); for (String node : nodes) { OfflineMessageRequest.Item item = new OfflineMessageRequest.Item(node); @@ -214,10 +220,11 @@ public class OfflineMessageManager { /** * Deletes all offline messages of the user. * - * @throws XMPPException If the user is not allowed to make this request or the server does + * @throws XMPPErrorException If the user is not allowed to make this request or the server does * not support offline message retrieval. + * @throws NoResponseException if there was no response from the server. */ - public void deleteMessages() throws XMPPException { + public void deleteMessages() throws NoResponseException, XMPPErrorException { OfflineMessageRequest request = new OfflineMessageRequest(); request.setPurge(true); connection.createPacketCollectorAndSend(request).nextResultOrThrow(); diff --git a/extensions/src/main/java/org/jivesoftware/smackx/ping/PingManager.java b/extensions/src/main/java/org/jivesoftware/smackx/ping/PingManager.java index ec5944842..91e265863 100644 --- a/extensions/src/main/java/org/jivesoftware/smackx/ping/PingManager.java +++ b/extensions/src/main/java/org/jivesoftware/smackx/ping/PingManager.java @@ -23,15 +23,18 @@ import java.util.Set; import java.util.WeakHashMap; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; +import java.util.logging.Level; import java.util.logging.Logger; +import org.jivesoftware.smack.SmackException; +import org.jivesoftware.smack.SmackException.NoResponseException; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.ConnectionCreationListener; import org.jivesoftware.smack.ConnectionListener; import org.jivesoftware.smack.Manager; import org.jivesoftware.smack.PacketListener; -import org.jivesoftware.smack.SmackError; import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.filter.AndFilter; import org.jivesoftware.smack.filter.IQTypeFilter; import org.jivesoftware.smack.filter.PacketFilter; @@ -163,14 +166,15 @@ public class PingManager extends Manager { * @param jid The id of the entity the ping is being sent to * @param pingTimeout The time to wait for a reply * @return true if a reply was received from the entity, false otherwise. + * @throws NoResponseException if there was no response from the server. */ - public boolean ping(String jid, long pingTimeout) { + public boolean ping(String jid, long pingTimeout) throws NoResponseException { Ping ping = new Ping(jid); try { connection().createPacketCollectorAndSend(ping).nextResultOrThrow(); } catch (XMPPException exc) { - return (jid.equals(connection().getServiceName()) && (exc.getSmackError() != SmackError.NO_RESPONSE_FROM_SERVER)); + return jid.equals(connection().getServiceName()); } return true; } @@ -181,8 +185,9 @@ public class PingManager extends Manager { * * @param jid The id of the entity the ping is being sent to * @return true if a reply was received from the entity, false otherwise. + * @throws SmackException if there was no response from the server. */ - public boolean ping(String jid) { + public boolean ping(String jid) throws SmackException { return ping(jid, connection().getPacketReplyTimeout()); } @@ -191,9 +196,10 @@ public class PingManager extends Manager { * * @param jid The id of the entity the query is being sent to * @return true if it supports ping, false otherwise. - * @throws XMPPException An XMPP related error occurred during the request + * @throws XMPPErrorException An XMPP related error occurred during the request + * @throws NoResponseException if there was no response from the server. */ - public boolean isPingSupported(String jid) throws XMPPException { + public boolean isPingSupported(String jid) throws NoResponseException, XMPPErrorException { return ServiceDiscoveryManager.getInstanceFor(connection()).supportsFeature(jid, PingManager.NAMESPACE); } @@ -205,8 +211,9 @@ public class PingManager extends Manager { * {@link #isPingSupported(String)} is false. * * @return true if a reply was received from the server, false otherwise. + * @throws SmackException if there was no response from the server. */ - public boolean pingMyServer() { + public boolean pingMyServer() throws SmackException { return pingMyServer(true); } @@ -219,8 +226,9 @@ public class PingManager extends Manager { * * @param notifyListeners Notify the PingFailedListener in case of error if true * @return true if the user's server could be pinged. + * @throws SmackException if there was no response from the server. */ - public boolean pingMyServer(boolean notifyListeners) { + public boolean pingMyServer(boolean notifyListeners) throws SmackException { boolean res = ping(connection().getServiceName()); if (res) { pongReceived(); @@ -327,7 +335,13 @@ public class PingManager extends Manager { return; } } - res = pingMyServer(false); + try { + res = pingMyServer(false); + } + catch (SmackException e) { + LOGGER.log(Level.WARNING, "SmackError while pinging server", e); + res = false; + } // stop when we receive a pong back if (res) { lastSuccessfulAutomaticPing = System.currentTimeMillis(); diff --git a/extensions/src/main/java/org/jivesoftware/smackx/privacy/PrivacyListManager.java b/extensions/src/main/java/org/jivesoftware/smackx/privacy/PrivacyListManager.java index b8ce18d79..033f6f439 100644 --- a/extensions/src/main/java/org/jivesoftware/smackx/privacy/PrivacyListManager.java +++ b/extensions/src/main/java/org/jivesoftware/smackx/privacy/PrivacyListManager.java @@ -23,11 +23,12 @@ import java.util.Map; import java.util.Set; import java.util.WeakHashMap; +import org.jivesoftware.smack.SmackException.NoResponseException; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.ConnectionCreationListener; import org.jivesoftware.smack.Manager; import org.jivesoftware.smack.PacketListener; -import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.filter.AndFilter; import org.jivesoftware.smack.filter.IQTypeFilter; import org.jivesoftware.smack.filter.PacketExtensionFilter; @@ -139,9 +140,10 @@ public class PrivacyListManager extends Manager { * @param requestPrivacy is the {@link Privacy} packet configured properly whose XML * will be sent to the server. * @return a new {@link Privacy} with the data received from the server. - * @exception XMPPException if the request or the answer failed, it raises an exception. + * @throws XMPPErrorException + * @throws NoResponseException */ - private Privacy getRequest(Privacy requestPrivacy) throws XMPPException { + private Privacy getRequest(Privacy requestPrivacy) throws NoResponseException, XMPPErrorException { // The request is a get iq type requestPrivacy.setType(Privacy.Type.GET); requestPrivacy.setFrom(this.getUser()); @@ -157,9 +159,10 @@ public class PrivacyListManager extends Manager { * @param requestPrivacy is the {@link Privacy} packet configured properly whose xml will be * sent to the server. * @return a new {@link Privacy} with the data received from the server. - * @exception XMPPException if the request or the answer failed, it raises an exception. + * @throws XMPPErrorException + * @throws NoResponseException */ - private Packet setRequest(Privacy requestPrivacy) throws XMPPException { + private Packet setRequest(Privacy requestPrivacy) throws NoResponseException, XMPPErrorException { // The request is a get iq type requestPrivacy.setType(Privacy.Type.SET); requestPrivacy.setFrom(this.getUser()); @@ -171,9 +174,10 @@ public class PrivacyListManager extends Manager { * Answer a privacy containing the list structure without {@link PrivacyItem}. * * @return a Privacy with the list names. - * @throws XMPPException if an error occurs. + * @throws XMPPErrorException + * @throws NoResponseException */ - private Privacy getPrivacyWithListNames() throws XMPPException { + private Privacy getPrivacyWithListNames() throws NoResponseException, XMPPErrorException { // The request of the list is an empty privacy message Privacy request = new Privacy(); @@ -185,9 +189,10 @@ public class PrivacyListManager extends Manager { * Answer the active privacy list. * * @return the privacy list of the active list. - * @throws XMPPException if an error occurs. + * @throws XMPPErrorException + * @throws NoResponseException */ - public PrivacyList getActiveList() throws XMPPException { + public PrivacyList getActiveList() throws NoResponseException, XMPPErrorException { Privacy privacyAnswer = this.getPrivacyWithListNames(); String listName = privacyAnswer.getActiveName(); boolean isDefaultAndActive = privacyAnswer.getActiveName() != null @@ -201,9 +206,10 @@ public class PrivacyListManager extends Manager { * Answer the default privacy list. * * @return the privacy list of the default list. - * @throws XMPPException if an error occurs. + * @throws XMPPErrorException + * @throws NoResponseException */ - public PrivacyList getDefaultList() throws XMPPException { + public PrivacyList getDefaultList() throws NoResponseException, XMPPErrorException { Privacy privacyAnswer = this.getPrivacyWithListNames(); String listName = privacyAnswer.getDefaultName(); boolean isDefaultAndActive = privacyAnswer.getActiveName() != null @@ -218,9 +224,10 @@ public class PrivacyListManager extends Manager { * * @param listName the name of the list to get the allowed and blocked permissions. * @return a list of privacy items under the list listName. - * @throws XMPPException if an error occurs. + * @throws XMPPErrorException + * @throws NoResponseException */ - private List getPrivacyListItems(String listName) throws XMPPException { + private List getPrivacyListItems(String listName) throws NoResponseException, XMPPErrorException { // The request of the list is an privacy message with an empty list Privacy request = new Privacy(); request.setPrivacyList(listName, new ArrayList()); @@ -236,9 +243,10 @@ public class PrivacyListManager extends Manager { * * @param listName the name of the list to get the allowed and blocked permissions. * @return a privacy list under the list listName. - * @throws XMPPException if an error occurs. + * @throws XMPPErrorException + * @throws NoResponseException */ - public PrivacyList getPrivacyList(String listName) throws XMPPException { + public PrivacyList getPrivacyList(String listName) throws NoResponseException, XMPPErrorException { return new PrivacyList(false, false, listName, getPrivacyListItems(listName)); } @@ -246,9 +254,10 @@ public class PrivacyListManager extends Manager { * Answer every privacy list with the allowed and blocked permissions. * * @return an array of privacy lists. - * @throws XMPPException if an error occurs. + * @throws XMPPErrorException + * @throws NoResponseException */ - public PrivacyList[] getPrivacyLists() throws XMPPException { + public PrivacyList[] getPrivacyLists() throws NoResponseException, XMPPErrorException { Privacy privacyAnswer = this.getPrivacyWithListNames(); Set names = privacyAnswer.getPrivacyListNames(); PrivacyList[] lists = new PrivacyList[names.size()]; @@ -269,9 +278,10 @@ public class PrivacyListManager extends Manager { * Set or change the active list to listName. * * @param listName the list name to set as the active one. - * @exception XMPPException if the request or the answer failed, it raises an exception. + * @throws XMPPErrorException + * @throws NoResponseException */ - public void setActiveListName(String listName) throws XMPPException { + public void setActiveListName(String listName) throws NoResponseException, XMPPErrorException { // The request of the list is an privacy message with an empty list Privacy request = new Privacy(); request.setActiveName(listName); @@ -282,10 +292,10 @@ public class PrivacyListManager extends Manager { /** * Client declines the use of active lists. - * - * @throws XMPPException if an error occurs. + * @throws XMPPErrorException + * @throws NoResponseException */ - public void declineActiveList() throws XMPPException { + public void declineActiveList() throws NoResponseException, XMPPErrorException { // The request of the list is an privacy message with an empty list Privacy request = new Privacy(); request.setDeclineActiveList(true); @@ -298,9 +308,10 @@ public class PrivacyListManager extends Manager { * Set or change the default list to listName. * * @param listName the list name to set as the default one. - * @exception XMPPException if the request or the answer failed, it raises an exception. + * @throws XMPPErrorException + * @throws NoResponseException */ - public void setDefaultListName(String listName) throws XMPPException { + public void setDefaultListName(String listName) throws NoResponseException, XMPPErrorException { // The request of the list is an privacy message with an empty list Privacy request = new Privacy(); request.setDefaultName(listName); @@ -311,10 +322,10 @@ public class PrivacyListManager extends Manager { /** * Client declines the use of default lists. - * - * @throws XMPPException if an error occurs. + * @throws XMPPErrorException + * @throws NoResponseException */ - public void declineDefaultList() throws XMPPException { + public void declineDefaultList() throws NoResponseException, XMPPErrorException { // The request of the list is an privacy message with an empty list Privacy request = new Privacy(); request.setDeclineDefaultList(true); @@ -328,10 +339,11 @@ public class PrivacyListManager extends Manager { * * @param listName the list that has changed its content. * @param privacyItems a List with every privacy item in the list. - * @throws XMPPException if an error occurs. + * @throws XMPPErrorException + * @throws NoResponseException */ - public void createPrivacyList(String listName, List privacyItems) throws XMPPException { - this.updatePrivacyList(listName, privacyItems); + public void createPrivacyList(String listName, List privacyItems) throws NoResponseException, XMPPErrorException { + updatePrivacyList(listName, privacyItems); } /** @@ -341,9 +353,10 @@ public class PrivacyListManager extends Manager { * * @param listName the list that has changed its content. * @param privacyItems a List with every privacy item in the list. - * @throws XMPPException if an error occurs. + * @throws XMPPErrorException + * @throws NoResponseException */ - public void updatePrivacyList(String listName, List privacyItems) throws XMPPException { + public void updatePrivacyList(String listName, List privacyItems) throws NoResponseException, XMPPErrorException { // Build the privacy package to add or update the new list Privacy request = new Privacy(); request.setPrivacyList(listName, privacyItems); @@ -356,9 +369,10 @@ public class PrivacyListManager extends Manager { * Remove a privacy list. * * @param listName the list that has changed its content. - * @throws XMPPException if an error occurs. + * @throws XMPPErrorException + * @throws NoResponseException */ - public void deletePrivacyList(String listName) throws XMPPException { + public void deletePrivacyList(String listName) throws NoResponseException, XMPPErrorException { // The request of the list is an privacy message with an empty list Privacy request = new Privacy(); request.setPrivacyList(listName, new ArrayList()); @@ -385,9 +399,10 @@ public class PrivacyListManager extends Manager { * Check if the user's server supports privacy lists. * * @return true, if the server supports privacy lists, false otherwise. - * @throws XMPPException + * @throws XMPPErrorException + * @throws NoResponseException */ - public boolean isSupported() throws XMPPException { + public boolean isSupported() throws NoResponseException, XMPPErrorException{ return ServiceDiscoveryManager.getInstanceFor(connection()).supportsFeature( connection().getServiceName(), NAMESPACE); } diff --git a/extensions/src/main/java/org/jivesoftware/smackx/pubsub/LeafNode.java b/extensions/src/main/java/org/jivesoftware/smackx/pubsub/LeafNode.java index 601c7e0f1..701cdd462 100644 --- a/extensions/src/main/java/org/jivesoftware/smackx/pubsub/LeafNode.java +++ b/extensions/src/main/java/org/jivesoftware/smackx/pubsub/LeafNode.java @@ -20,8 +20,9 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; +import org.jivesoftware.smack.SmackException.NoResponseException; import org.jivesoftware.smack.XMPPConnection; -import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.packet.IQ.Type; import org.jivesoftware.smackx.disco.packet.DiscoverItems; import org.jivesoftware.smackx.pubsub.packet.PubSub; @@ -46,11 +47,10 @@ public class LeafNode extends Node * {@link DiscoverItems} format. * * @return The item details in {@link DiscoverItems} format - * - * @throws XMPPException + * @throws XMPPErrorException + * @throws NoResponseException if there was no response from the server. */ - public DiscoverItems discoverItems() - throws XMPPException + public DiscoverItems discoverItems() throws NoResponseException, XMPPErrorException { DiscoverItems items = new DiscoverItems(); items.setTo(to); @@ -62,12 +62,11 @@ public class LeafNode extends Node * Get the current items stored in the node. * * @return List of {@link Item} in the node - * - * @throws XMPPException + * @throws XMPPErrorException + * @throws NoResponseException if there was no response from the server. */ @SuppressWarnings("unchecked") - public List getItems() - throws XMPPException + public List getItems() throws NoResponseException, XMPPErrorException { PubSub request = createPubsubPacket(Type.GET, new GetItemsRequest(getId())); @@ -84,12 +83,11 @@ public class LeafNode extends Node * @param subscriptionId - The subscription id for the * associated subscription. * @return List of {@link Item} in the node - * - * @throws XMPPException + * @throws XMPPErrorException + * @throws NoResponseException if there was no response from the server. */ @SuppressWarnings("unchecked") - public List getItems(String subscriptionId) - throws XMPPException + public List getItems(String subscriptionId) throws NoResponseException, XMPPErrorException { PubSub request = createPubsubPacket(Type.GET, new GetItemsRequest(getId(), subscriptionId)); @@ -108,12 +106,11 @@ public class LeafNode extends Node * @param ids Item ids of the items to retrieve * * @return The list of {@link Item} with payload - * - * @throws XMPPException + * @throws XMPPErrorException + * @throws NoResponseException if there was no response from the server. */ @SuppressWarnings("unchecked") - public List getItems(Collection ids) - throws XMPPException + public List getItems(Collection ids) throws NoResponseException, XMPPErrorException { List itemList = new ArrayList(ids.size()); @@ -134,12 +131,11 @@ public class LeafNode extends Node * @param maxItems Maximum number of items to return * * @return List of {@link Item} - * - * @throws XMPPException + * @throws XMPPErrorException + * @throws NoResponseException if there was no response from the server. */ @SuppressWarnings("unchecked") - public List getItems(int maxItems) - throws XMPPException + public List getItems(int maxItems) throws NoResponseException, XMPPErrorException { PubSub request = createPubsubPacket(Type.GET, new GetItemsRequest(getId(), maxItems)); @@ -157,12 +153,11 @@ public class LeafNode extends Node * on. * * @return List of {@link Item} - * - * @throws XMPPException + * @throws XMPPErrorException + * @throws NoResponseException if there was no response from the server. */ @SuppressWarnings("unchecked") - public List getItems(int maxItems, String subscriptionId) - throws XMPPException + public List getItems(int maxItems, String subscriptionId) throws NoResponseException, XMPPErrorException { PubSub request = createPubsubPacket(Type.GET, new GetItemsRequest(getId(), subscriptionId, maxItems)); @@ -244,11 +239,11 @@ public class LeafNode extends Node * on failure. * * For asynchronous calls, use {@link #publish() publish()}. + * @throws XMPPErrorException + * @throws NoResponseException * - * @throws XMPPException */ - public void send() - throws XMPPException + public void send() throws NoResponseException, XMPPErrorException { PubSub packet = createPubsubPacket(Type.SET, new NodeExtension(PubSubElementType.PUBLISH, getId())); @@ -273,12 +268,12 @@ public class LeafNode extends Node * For asynchronous calls, use {@link #publish(Item) publish(Item)}. * * @param item - The item being sent + * @throws XMPPErrorException + * @throws NoResponseException * - * @throws XMPPException */ @SuppressWarnings("unchecked") - public void send(T item) - throws XMPPException + public void send(T item) throws NoResponseException, XMPPErrorException { Collection items = new ArrayList(1); items.add((item == null ? (T)new Item() : item)); @@ -297,11 +292,11 @@ public class LeafNode extends Node * For asynchronous calls, use {@link #publish(Collection) publish(Collection))}. * * @param items - The collection of {@link Item} objects being sent + * @throws XMPPErrorException + * @throws NoResponseException * - * @throws XMPPException */ - public void send(Collection items) - throws XMPPException + public void send(Collection items) throws NoResponseException, XMPPErrorException { PubSub packet = createPubsubPacket(Type.SET, new PublishItem(getId(), items)); @@ -313,11 +308,10 @@ public class LeafNode extends Node * *

Note: Some implementations may keep the last item * sent. - * - * @throws XMPPException + * @throws XMPPErrorException + * @throws NoResponseException if there was no response from the server. */ - public void deleteAllItems() - throws XMPPException + public void deleteAllItems() throws NoResponseException, XMPPErrorException { PubSub request = createPubsubPacket(Type.SET, new NodeExtension(PubSubElementType.PURGE_OWNER, getId()), PubSubElementType.PURGE_OWNER.getNamespace()); @@ -328,11 +322,10 @@ public class LeafNode extends Node * Delete the item with the specified id from the node. * * @param itemId The id of the item - * - * @throws XMPPException + * @throws XMPPErrorException + * @throws NoResponseException */ - public void deleteItem(String itemId) - throws XMPPException + public void deleteItem(String itemId) throws NoResponseException, XMPPErrorException { Collection items = new ArrayList(1); items.add(itemId); @@ -343,11 +336,10 @@ public class LeafNode extends Node * Delete the items with the specified id's from the node. * * @param itemIds The list of id's of items to delete - * - * @throws XMPPException + * @throws XMPPErrorException + * @throws NoResponseException if there was no response from the server. */ - public void deleteItem(Collection itemIds) - throws XMPPException + public void deleteItem(Collection itemIds) throws NoResponseException, XMPPErrorException { List items = new ArrayList(itemIds.size()); diff --git a/extensions/src/main/java/org/jivesoftware/smackx/pubsub/Node.java b/extensions/src/main/java/org/jivesoftware/smackx/pubsub/Node.java index 0092e926a..fc92be028 100644 --- a/extensions/src/main/java/org/jivesoftware/smackx/pubsub/Node.java +++ b/extensions/src/main/java/org/jivesoftware/smackx/pubsub/Node.java @@ -23,8 +23,9 @@ import java.util.List; import java.util.concurrent.ConcurrentHashMap; import org.jivesoftware.smack.PacketListener; +import org.jivesoftware.smack.SmackException.NoResponseException; import org.jivesoftware.smack.XMPPConnection; -import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.filter.OrFilter; import org.jivesoftware.smack.filter.PacketFilter; import org.jivesoftware.smack.packet.Message; @@ -91,9 +92,10 @@ abstract public class Node * via the {@link #sendConfigurationForm(Form)}. * * @return the configuration form + * @throws XMPPErrorException + * @throws NoResponseException */ - public ConfigureForm getNodeConfiguration() - throws XMPPException + public ConfigureForm getNodeConfiguration() throws NoResponseException, XMPPErrorException { Packet reply = sendPubsubPacket(Type.GET, new NodeExtension(PubSubElementType.CONFIGURE_OWNER, getId()), PubSubNamespace.OWNER); return NodeUtils.getFormFromPacket(reply, PubSubElementType.CONFIGURE_OWNER); @@ -103,9 +105,10 @@ abstract public class Node * Update the configuration with the contents of the new {@link Form} * * @param submitForm + * @throws XMPPErrorException + * @throws NoResponseException */ - public void sendConfigurationForm(Form submitForm) - throws XMPPException + public void sendConfigurationForm(Form submitForm) throws NoResponseException, XMPPErrorException { PubSub packet = createPubsubPacket(Type.SET, new FormNode(FormNodeType.CONFIGURE_OWNER, getId(), submitForm), PubSubNamespace.OWNER); con.createPacketCollectorAndSend(packet).nextResultOrThrow(); @@ -115,11 +118,10 @@ abstract public class Node * Discover node information in standard {@link DiscoverInfo} format. * * @return The discovery information about the node. - * - * @throws XMPPException + * @throws XMPPErrorException + * @throws NoResponseException if there was no response from the server. */ - public DiscoverInfo discoverInfo() - throws XMPPException + public DiscoverInfo discoverInfo() throws NoResponseException, XMPPErrorException { DiscoverInfo info = new DiscoverInfo(); info.setTo(to); @@ -131,11 +133,11 @@ abstract public class Node * Get the subscriptions currently associated with this node. * * @return List of {@link Subscription} + * @throws XMPPErrorException + * @throws NoResponseException * - * @throws XMPPException */ - public List getSubscriptions() - throws XMPPException + public List getSubscriptions() throws NoResponseException, XMPPErrorException { PubSub reply = (PubSub)sendPubsubPacket(Type.GET, new NodeExtension(PubSubElementType.SUBSCRIPTIONS, getId())); SubscriptionsExtension subElem = (SubscriptionsExtension)reply.getExtension(PubSubElementType.SUBSCRIPTIONS); @@ -155,10 +157,10 @@ abstract public class Node * the caller can configure it but is not required to do so. * @param jid The jid to subscribe as. * @return The subscription - * @exception XMPPException + * @throws XMPPErrorException + * @throws NoResponseException */ - public Subscription subscribe(String jid) - throws XMPPException + public Subscription subscribe(String jid) throws NoResponseException, XMPPErrorException { PubSub reply = (PubSub)sendPubsubPacket(Type.SET, new SubscribeExtension(jid, getId())); return (Subscription)reply.getExtension(PubSubElementType.SUBSCRIPTION); @@ -178,10 +180,10 @@ abstract public class Node * the caller can configure it but is not required to do so. * @param jid The jid to subscribe as. * @return The subscription - * @exception XMPPException + * @throws XMPPErrorException + * @throws NoResponseException */ - public Subscription subscribe(String jid, SubscribeForm subForm) - throws XMPPException + public Subscription subscribe(String jid, SubscribeForm subForm) throws NoResponseException, XMPPErrorException { PubSub request = createPubsubPacket(Type.SET, new SubscribeExtension(jid, getId())); request.addExtension(new FormNode(FormNodeType.OPTIONS, subForm)); @@ -195,11 +197,11 @@ abstract public class Node * use {@link #unsubscribe(String, String)}. * * @param jid The JID used to subscribe to the node + * @throws XMPPErrorException + * @throws NoResponseException * - * @throws XMPPException */ - public void unsubscribe(String jid) - throws XMPPException + public void unsubscribe(String jid) throws NoResponseException, XMPPErrorException { unsubscribe(jid, null); } @@ -209,11 +211,10 @@ abstract public class Node * * @param jid The JID used to subscribe to the node * @param subscriptionId The id of the subscription being removed - * - * @throws XMPPException + * @throws XMPPErrorException + * @throws NoResponseException */ - public void unsubscribe(String jid, String subscriptionId) - throws XMPPException + public void unsubscribe(String jid, String subscriptionId) throws NoResponseException, XMPPErrorException { sendPubsubPacket(Type.SET, new UnsubscribeExtension(jid, getId(), subscriptionId)); } @@ -223,11 +224,10 @@ abstract public class Node * via the {@link #sendConfigurationForm(Form)}. * * @return A subscription options form - * - * @throws XMPPException + * @throws XMPPErrorException + * @throws NoResponseException */ - public SubscribeForm getSubscriptionOptions(String jid) - throws XMPPException + public SubscribeForm getSubscriptionOptions(String jid) throws NoResponseException, XMPPErrorException { return getSubscriptionOptions(jid, null); } @@ -240,11 +240,11 @@ abstract public class Node * @param subscriptionId The subscription id * * @return The subscription option form + * @throws XMPPErrorException + * @throws NoResponseException * - * @throws XMPPException */ - public SubscribeForm getSubscriptionOptions(String jid, String subscriptionId) - throws XMPPException + public SubscribeForm getSubscriptionOptions(String jid, String subscriptionId) throws NoResponseException, XMPPErrorException { PubSub packet = (PubSub)sendPubsubPacket(Type.GET, new OptionsExtension(jid, getId(), subscriptionId)); FormNode ext = (FormNode)packet.getExtension(PubSubElementType.OPTIONS); @@ -349,14 +349,12 @@ abstract public class Node return PubSubManager.createPubsubPacket(to, type, ext, ns); } - protected Packet sendPubsubPacket(Type type, NodeExtension ext) - throws XMPPException + protected Packet sendPubsubPacket(Type type, NodeExtension ext) throws NoResponseException, XMPPErrorException { return PubSubManager.sendPubsubPacket(con, to, type, ext); } - protected Packet sendPubsubPacket(Type type, NodeExtension ext, PubSubNamespace ns) - throws XMPPException + protected Packet sendPubsubPacket(Type type, NodeExtension ext, PubSubNamespace ns) throws NoResponseException, XMPPErrorException { return PubSubManager.sendPubsubPacket(con, to, type, ext, ns); } diff --git a/extensions/src/main/java/org/jivesoftware/smackx/pubsub/PubSubManager.java b/extensions/src/main/java/org/jivesoftware/smackx/pubsub/PubSubManager.java index df6018ab3..86b34b39b 100644 --- a/extensions/src/main/java/org/jivesoftware/smackx/pubsub/PubSubManager.java +++ b/extensions/src/main/java/org/jivesoftware/smackx/pubsub/PubSubManager.java @@ -20,8 +20,9 @@ import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +import org.jivesoftware.smack.SmackException.NoResponseException; import org.jivesoftware.smack.XMPPConnection; -import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.packet.IQ.Type; import org.jivesoftware.smack.packet.Packet; import org.jivesoftware.smack.packet.PacketExtension; @@ -78,10 +79,10 @@ final public class PubSubManager * Creates an instant node, if supported. * * @return The node that was created - * @exception XMPPException + * @throws XMPPErrorException + * @throws NoResponseException */ - public LeafNode createNode() - throws XMPPException + public LeafNode createNode() throws NoResponseException, XMPPErrorException { PubSub reply = (PubSub)sendPubsubPacket(Type.SET, new NodeExtension(PubSubElementType.CREATE)); NodeExtension elem = (NodeExtension)reply.getExtension("create", PubSubNamespace.BASIC.getXmlns()); @@ -99,10 +100,10 @@ final public class PubSubManager * @param id The id of the node, which must be unique within the * pubsub service * @return The node that was created - * @exception XMPPException + * @throws XMPPErrorException + * @throws NoResponseException */ - public LeafNode createNode(String id) - throws XMPPException + public LeafNode createNode(String id) throws NoResponseException, XMPPErrorException { return (LeafNode)createNode(id, null); } @@ -116,10 +117,10 @@ final public class PubSubManager * pubsub service * @param config The configuration for the node * @return The node that was created - * @exception XMPPException + * @throws XMPPErrorException + * @throws NoResponseException */ - public Node createNode(String name, Form config) - throws XMPPException + public Node createNode(String name, Form config) throws NoResponseException, XMPPErrorException { PubSub request = createPubsubPacket(to, Type.SET, new NodeExtension(PubSubElementType.CREATE, name)); boolean isLeafNode = true; @@ -149,11 +150,11 @@ final public class PubSubManager * * @param id - The unique id of the node * @return the node - * @throws XMPPException The node does not exist + * @throws XMPPErrorException The node does not exist + * @throws NoResponseException if there was no response from the server. */ @SuppressWarnings("unchecked") - public T getNode(String id) - throws XMPPException + public T getNode(String id) throws NoResponseException, XMPPErrorException { Node node = nodeMap.get(id); @@ -186,11 +187,10 @@ final public class PubSubManager * @param nodeId - The id of the collection node for which the child * nodes will be returned. * @return {@link DiscoverItems} representing the existing nodes - * - * @throws XMPPException + * @throws XMPPErrorException + * @throws NoResponseException if there was no response from the server. */ - public DiscoverItems discoverNodes(String nodeId) - throws XMPPException + public DiscoverItems discoverNodes(String nodeId) throws NoResponseException, XMPPErrorException { DiscoverItems items = new DiscoverItems(); @@ -205,11 +205,10 @@ final public class PubSubManager * Gets the subscriptions on the root node. * * @return List of exceptions - * - * @throws XMPPException + * @throws XMPPErrorException + * @throws NoResponseException */ - public List getSubscriptions() - throws XMPPException + public List getSubscriptions() throws NoResponseException, XMPPErrorException { Packet reply = sendPubsubPacket(Type.GET, new NodeExtension(PubSubElementType.SUBSCRIPTIONS)); SubscriptionsExtension subElem = (SubscriptionsExtension)reply.getExtension(PubSubElementType.SUBSCRIPTIONS.getElementName(), PubSubElementType.SUBSCRIPTIONS.getNamespace().getXmlns()); @@ -220,11 +219,11 @@ final public class PubSubManager * Gets the affiliations on the root node. * * @return List of affiliations + * @throws XMPPErrorException + * @throws NoResponseException * - * @throws XMPPException */ - public List getAffiliations() - throws XMPPException + public List getAffiliations() throws NoResponseException, XMPPErrorException { PubSub reply = (PubSub)sendPubsubPacket(Type.GET, new NodeExtension(PubSubElementType.AFFILIATIONS)); AffiliationsExtension listElem = (AffiliationsExtension)reply.getExtension(PubSubElementType.AFFILIATIONS); @@ -235,10 +234,10 @@ final public class PubSubManager * Delete the specified node * * @param nodeId - * @throws XMPPException + * @throws XMPPErrorException + * @throws NoResponseException */ - public void deleteNode(String nodeId) - throws XMPPException + public void deleteNode(String nodeId) throws NoResponseException, XMPPErrorException { sendPubsubPacket(Type.SET, new NodeExtension(PubSubElementType.DELETE, nodeId), PubSubElementType.DELETE.getNamespace()); nodeMap.remove(nodeId); @@ -248,9 +247,10 @@ final public class PubSubManager * Returns the default settings for Node configuration. * * @return configuration form containing the default settings. + * @throws XMPPErrorException + * @throws NoResponseException */ - public ConfigureForm getDefaultConfiguration() - throws XMPPException + public ConfigureForm getDefaultConfiguration() throws NoResponseException, XMPPErrorException { // Errors will cause exceptions in getReply, so it only returns // on success. @@ -263,24 +263,21 @@ final public class PubSubManager * as a standard {@link DiscoverInfo} instance. * * @return The supported features - * - * @throws XMPPException + * @throws XMPPErrorException + * @throws NoResponseException */ - public DiscoverInfo getSupportedFeatures() - throws XMPPException + public DiscoverInfo getSupportedFeatures() throws NoResponseException, XMPPErrorException { ServiceDiscoveryManager mgr = ServiceDiscoveryManager.getInstanceFor(con); return mgr.discoverInfo(to); } - private Packet sendPubsubPacket(Type type, PacketExtension ext, PubSubNamespace ns) - throws XMPPException + private Packet sendPubsubPacket(Type type, PacketExtension ext, PubSubNamespace ns) throws NoResponseException, XMPPErrorException { return sendPubsubPacket(con, to, type, ext, ns); } - private Packet sendPubsubPacket(Type type, PacketExtension ext) - throws XMPPException + private Packet sendPubsubPacket(Type type, PacketExtension ext) throws NoResponseException, XMPPErrorException { return sendPubsubPacket(type, ext, null); } @@ -305,26 +302,22 @@ final public class PubSubManager return request; } - static Packet sendPubsubPacket(XMPPConnection con, String to, Type type, PacketExtension ext) - throws XMPPException + static Packet sendPubsubPacket(XMPPConnection con, String to, Type type, PacketExtension ext) throws NoResponseException, XMPPErrorException { return sendPubsubPacket(con, to, type, ext, null); } - static Packet sendPubsubPacket(XMPPConnection con, String to, Type type, PacketExtension ext, PubSubNamespace ns) - throws XMPPException + static Packet sendPubsubPacket(XMPPConnection con, String to, Type type, PacketExtension ext, PubSubNamespace ns) throws NoResponseException, XMPPErrorException { return con.createPacketCollectorAndSend(createPubsubPacket(to, type, ext, ns)).nextResultOrThrow(); } - static Packet sendPubsubPacket(XMPPConnection con, String to, Type type, PubSub packet) - throws XMPPException + static Packet sendPubsubPacket(XMPPConnection con, String to, Type type, PubSub packet) throws NoResponseException, XMPPErrorException { return sendPubsubPacket(con, to, type, packet, null); } - static Packet sendPubsubPacket(XMPPConnection con, String to, Type type, PubSub packet, PubSubNamespace ns) - throws XMPPException + static Packet sendPubsubPacket(XMPPConnection con, String to, Type type, PubSub packet, PubSubNamespace ns) throws NoResponseException, XMPPErrorException { return con.createPacketCollectorAndSend(packet).nextResultOrThrow(); } diff --git a/extensions/src/main/java/org/jivesoftware/smackx/receipts/DeliveryReceiptManager.java b/extensions/src/main/java/org/jivesoftware/smackx/receipts/DeliveryReceiptManager.java index 9e4165da0..69750aeb5 100644 --- a/extensions/src/main/java/org/jivesoftware/smackx/receipts/DeliveryReceiptManager.java +++ b/extensions/src/main/java/org/jivesoftware/smackx/receipts/DeliveryReceiptManager.java @@ -22,6 +22,7 @@ import java.util.Map; import java.util.Set; import java.util.WeakHashMap; +import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.ConnectionCreationListener; import org.jivesoftware.smack.Manager; @@ -88,15 +89,12 @@ public class DeliveryReceiptManager extends Manager implements PacketListener { * * @param jid * @return true if supported + * @throws SmackException if there was no response from the server. + * @throws XMPPException */ - public boolean isSupported(String jid) { - try { - return ServiceDiscoveryManager.getInstanceFor(connection()).supportsFeature(jid, - DeliveryReceipt.NAMESPACE); - } - catch (XMPPException e) { - return false; - } + public boolean isSupported(String jid) throws SmackException, XMPPException { + return ServiceDiscoveryManager.getInstanceFor(connection()).supportsFeature(jid, + DeliveryReceipt.NAMESPACE); } // handle incoming receipts and receipt requests diff --git a/extensions/src/main/java/org/jivesoftware/smackx/search/UserSearch.java b/extensions/src/main/java/org/jivesoftware/smackx/search/UserSearch.java index 122c9e422..bee4a56fb 100644 --- a/extensions/src/main/java/org/jivesoftware/smackx/search/UserSearch.java +++ b/extensions/src/main/java/org/jivesoftware/smackx/search/UserSearch.java @@ -16,8 +16,9 @@ */ package org.jivesoftware.smackx.search; +import org.jivesoftware.smack.SmackException.NoResponseException; import org.jivesoftware.smack.XMPPConnection; -import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.provider.IQProvider; import org.jivesoftware.smack.util.PacketParserUtils; @@ -58,10 +59,10 @@ public class UserSearch extends IQ { * @param con the current XMPPConnection. * @param searchService the search service to use. (ex. search.jivesoftware.com) * @return the search form received by the server. - * @throws org.jivesoftware.smack.XMPPException - * thrown if a server error has occurred. + * @throws XMPPErrorException + * @throws NoResponseException */ - public Form getSearchForm(XMPPConnection con, String searchService) throws XMPPException { + public Form getSearchForm(XMPPConnection con, String searchService) throws NoResponseException, XMPPErrorException { UserSearch search = new UserSearch(); search.setType(IQ.Type.GET); search.setTo(searchService); @@ -77,10 +78,10 @@ public class UserSearch extends IQ { * @param searchForm the Form to send for querying. * @param searchService the search service to use. (ex. search.jivesoftware.com) * @return ReportedData the data found from the query. - * @throws org.jivesoftware.smack.XMPPException - * thrown if a server error has occurred. + * @throws XMPPErrorException + * @throws NoResponseException */ - public ReportedData sendSearchForm(XMPPConnection con, Form searchForm, String searchService) throws XMPPException { + public ReportedData sendSearchForm(XMPPConnection con, Form searchForm, String searchService) throws NoResponseException, XMPPErrorException { UserSearch search = new UserSearch(); search.setType(IQ.Type.SET); search.setTo(searchService); @@ -97,10 +98,10 @@ public class UserSearch extends IQ { * @param searchForm the Form to send for querying. * @param searchService the search service to use. (ex. search.jivesoftware.com) * @return ReportedData the data found from the query. - * @throws org.jivesoftware.smack.XMPPException - * thrown if a server error has occurred. + * @throws XMPPErrorException + * @throws NoResponseException */ - public ReportedData sendSimpleSearchForm(XMPPConnection con, Form searchForm, String searchService) throws XMPPException { + public ReportedData sendSimpleSearchForm(XMPPConnection con, Form searchForm, String searchService) throws NoResponseException, XMPPErrorException { SimpleUserSearch search = new SimpleUserSearch(); search.setForm(searchForm); search.setType(IQ.Type.SET); diff --git a/extensions/src/main/java/org/jivesoftware/smackx/search/UserSearchManager.java b/extensions/src/main/java/org/jivesoftware/smackx/search/UserSearchManager.java index 7b7e0515c..b70e155bd 100644 --- a/extensions/src/main/java/org/jivesoftware/smackx/search/UserSearchManager.java +++ b/extensions/src/main/java/org/jivesoftware/smackx/search/UserSearchManager.java @@ -16,8 +16,10 @@ */ package org.jivesoftware.smackx.search; +import org.jivesoftware.smack.SmackException.NoResponseException; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smackx.disco.ServiceDiscoveryManager; import org.jivesoftware.smackx.disco.packet.DiscoverInfo; import org.jivesoftware.smackx.disco.packet.DiscoverItems; @@ -66,9 +68,10 @@ public class UserSearchManager { * * @param searchService the search service to query. * @return the form to fill out to perform a search. - * @throws XMPPException thrown if a server error has occurred. + * @throws XMPPErrorException + * @throws NoResponseException */ - public Form getSearchForm(String searchService) throws XMPPException { + public Form getSearchForm(String searchService) throws NoResponseException, XMPPErrorException { return userSearch.getSearchForm(con, searchService); } @@ -79,9 +82,10 @@ public class UserSearchManager { * @param searchForm the Form to submit for searching. * @param searchService the name of the search service to use. * @return the ReportedData returned by the server. - * @throws XMPPException thrown if a server error has occurred. + * @throws XMPPErrorException + * @throws NoResponseException */ - public ReportedData getSearchResults(Form searchForm, String searchService) throws XMPPException { + public ReportedData getSearchResults(Form searchForm, String searchService) throws NoResponseException, XMPPErrorException { return userSearch.sendSearchForm(con, searchForm, searchService); } @@ -90,9 +94,10 @@ public class UserSearchManager { * Returns a collection of search services found on the server. * * @return a Collection of search services found on the server. - * @throws XMPPException thrown if a server error has occurred. + * @throws XMPPErrorException + * @throws NoResponseException */ - public Collection getSearchServices() throws XMPPException { + public Collection getSearchServices() throws NoResponseException, XMPPErrorException { final List searchServices = new ArrayList(); ServiceDiscoveryManager discoManager = ServiceDiscoveryManager.getInstanceFor(con); DiscoverItems items = discoManager.discoverItems(con.getServiceName()); diff --git a/extensions/src/main/java/org/jivesoftware/smackx/sharedgroups/SharedGroupManager.java b/extensions/src/main/java/org/jivesoftware/smackx/sharedgroups/SharedGroupManager.java index d7ef10a80..618e7280a 100644 --- a/extensions/src/main/java/org/jivesoftware/smackx/sharedgroups/SharedGroupManager.java +++ b/extensions/src/main/java/org/jivesoftware/smackx/sharedgroups/SharedGroupManager.java @@ -16,8 +16,9 @@ */ package org.jivesoftware.smackx.sharedgroups; +import org.jivesoftware.smack.SmackException.NoResponseException; import org.jivesoftware.smack.XMPPConnection; -import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smackx.sharedgroups.packet.SharedGroupsInfo; @@ -39,8 +40,10 @@ public class SharedGroupManager { * * @param connection connection to use to get the user's shared groups. * @return collection with the shared groups' name of the logged user. + * @throws XMPPErrorException + * @throws NoResponseException */ - public static List getSharedGroups(XMPPConnection connection) throws XMPPException { + public static List getSharedGroups(XMPPConnection connection) throws NoResponseException, XMPPErrorException { // Discover the shared groups of the logged user SharedGroupsInfo info = new SharedGroupsInfo(); info.setType(IQ.Type.GET); diff --git a/extensions/src/main/java/org/jivesoftware/smackx/time/EntityTimeManager.java b/extensions/src/main/java/org/jivesoftware/smackx/time/EntityTimeManager.java index 20a37a81d..0aa77585d 100644 --- a/extensions/src/main/java/org/jivesoftware/smackx/time/EntityTimeManager.java +++ b/extensions/src/main/java/org/jivesoftware/smackx/time/EntityTimeManager.java @@ -19,11 +19,12 @@ package org.jivesoftware.smackx.time; import java.util.Map; import java.util.WeakHashMap; +import org.jivesoftware.smack.SmackException.NoResponseException; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.ConnectionCreationListener; import org.jivesoftware.smack.Manager; import org.jivesoftware.smack.PacketListener; -import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.filter.AndFilter; import org.jivesoftware.smack.filter.IQTypeFilter; import org.jivesoftware.smack.filter.PacketFilter; @@ -96,11 +97,11 @@ public class EntityTimeManager extends Manager { enabled = false; } - public boolean isTimeSupported(String jid) throws XMPPException { + public boolean isTimeSupported(String jid) throws NoResponseException, XMPPErrorException { return ServiceDiscoveryManager.getInstanceFor(connection()).supportsFeature(jid, Time.NAMESPACE); } - public Time getTime(String jid) throws XMPPException { + public Time getTime(String jid) throws NoResponseException, XMPPErrorException { if (!isTimeSupported(jid)) return null; diff --git a/extensions/src/main/java/org/jivesoftware/smackx/vcardtemp/VCardManager.java b/extensions/src/main/java/org/jivesoftware/smackx/vcardtemp/VCardManager.java index 001acee57..4a58ed2a8 100644 --- a/extensions/src/main/java/org/jivesoftware/smackx/vcardtemp/VCardManager.java +++ b/extensions/src/main/java/org/jivesoftware/smackx/vcardtemp/VCardManager.java @@ -17,8 +17,9 @@ package org.jivesoftware.smackx.vcardtemp; import org.jivesoftware.smack.ConnectionCreationListener; +import org.jivesoftware.smack.SmackException.NoResponseException; import org.jivesoftware.smack.XMPPConnection; -import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smackx.disco.ServiceDiscoveryManager; public class VCardManager { @@ -40,9 +41,10 @@ public class VCardManager { * @param jid * @param connection * @return true if the given entity understands the vCard-XML format and exchange. - * @throws XMPPException If there was an exception while determining the support. + * @throws XMPPErrorException + * @throws NoResponseException */ - public static boolean isSupported(String jid, XMPPConnection connection) throws XMPPException { + public static boolean isSupported(String jid, XMPPConnection connection) throws NoResponseException, XMPPErrorException { return ServiceDiscoveryManager.getInstanceFor(connection).supportsFeature(jid, NAMESPACE); } } diff --git a/extensions/src/main/java/org/jivesoftware/smackx/vcardtemp/packet/VCard.java b/extensions/src/main/java/org/jivesoftware/smackx/vcardtemp/packet/VCard.java index 32add6568..48da1eb86 100644 --- a/extensions/src/main/java/org/jivesoftware/smackx/vcardtemp/packet/VCard.java +++ b/extensions/src/main/java/org/jivesoftware/smackx/vcardtemp/packet/VCard.java @@ -33,8 +33,9 @@ import java.util.Map.Entry; import java.util.logging.Level; import java.util.logging.Logger; +import org.jivesoftware.smack.SmackException.NoResponseException; import org.jivesoftware.smack.XMPPConnection; -import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.util.StringUtils; import org.jivesoftware.smackx.vcardtemp.VCardManager; @@ -515,9 +516,10 @@ public class VCard extends IQ { * NOTE: the method is asynchronous and does not wait for the returned value. * * @param connection the XMPPConnection to use. - * @throws XMPPException thrown if there was an issue setting the VCard in the server. + * @throws XMPPErrorException thrown if there was an issue setting the VCard in the server. + * @throws NoResponseException if there was no response from the server. */ - public void save(XMPPConnection connection) throws XMPPException { + public void save(XMPPConnection connection) throws NoResponseException, XMPPErrorException { checkAuthenticated(connection, true); setType(IQ.Type.SET); @@ -528,8 +530,10 @@ public class VCard extends IQ { /** * Load VCard information for a connected user. XMPPConnection should be authenticated * and not anonymous. + * @throws XMPPErrorException + * @throws NoResponseException */ - public void load(XMPPConnection connection) throws XMPPException { + public void load(XMPPConnection connection) throws NoResponseException, XMPPErrorException { checkAuthenticated(connection, true); setFrom(connection.getUser()); @@ -538,15 +542,17 @@ public class VCard extends IQ { /** * Load VCard information for a given user. XMPPConnection should be authenticated and not anonymous. + * @throws XMPPErrorException + * @throws NoResponseException if there was no response from the server. */ - public void load(XMPPConnection connection, String user) throws XMPPException { + public void load(XMPPConnection connection, String user) throws NoResponseException, XMPPErrorException { checkAuthenticated(connection, false); setTo(user); doLoad(connection, user); } - private void doLoad(XMPPConnection connection, String user) throws XMPPException { + private void doLoad(XMPPConnection connection, String user) throws NoResponseException, XMPPErrorException { setType(Type.GET); VCard result = (VCard) connection.createPacketCollectorAndSend(this).nextResultOrThrow(); copyFieldsFrom(result); diff --git a/extensions/src/main/java/org/jivesoftware/smackx/xhtmlim/XHTMLManager.java b/extensions/src/main/java/org/jivesoftware/smackx/xhtmlim/XHTMLManager.java index 2b21c3903..0900b36a7 100644 --- a/extensions/src/main/java/org/jivesoftware/smackx/xhtmlim/XHTMLManager.java +++ b/extensions/src/main/java/org/jivesoftware/smackx/xhtmlim/XHTMLManager.java @@ -18,16 +18,14 @@ package org.jivesoftware.smackx.xhtmlim; import org.jivesoftware.smack.ConnectionCreationListener; +import org.jivesoftware.smack.SmackException.NoResponseException; import org.jivesoftware.smack.XMPPConnection; -import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.packet.Message; import org.jivesoftware.smackx.disco.ServiceDiscoveryManager; -import org.jivesoftware.smackx.disco.packet.DiscoverInfo; import org.jivesoftware.smackx.xhtmlim.packet.XHTMLExtension; import java.util.Iterator; -import java.util.logging.Level; -import java.util.logging.Logger; /** * Manages XHTML formatted texts within messages. A XHTMLManager provides a high level access to @@ -37,9 +35,6 @@ import java.util.logging.Logger; * @author Gaston Dombiak */ public class XHTMLManager { - - private static final Logger LOGGER = Logger.getLogger(XHTMLManager.class.getName()); - private final static String namespace = "http://jabber.org/protocol/xhtml-im"; // Enable the XHTML support on every established connection @@ -131,16 +126,11 @@ public class XHTMLManager { * @param connection the connection to use to perform the service discovery * @param userID the user to check. A fully qualified xmpp ID, e.g. jdoe@example.com * @return a boolean indicating whether the specified user handles XHTML messages + * @throws XMPPErrorException + * @throws NoResponseException */ - public static boolean isServiceEnabled(XMPPConnection connection, String userID) { - try { - DiscoverInfo result = - ServiceDiscoveryManager.getInstanceFor(connection).discoverInfo(userID); - return result.containsFeature(namespace); - } - catch (XMPPException e) { - LOGGER.log(Level.SEVERE, "Error checking if service is available", e); - return false; - } + public static boolean isServiceEnabled(XMPPConnection connection, String userID) + throws NoResponseException, XMPPErrorException { + return ServiceDiscoveryManager.getInstanceFor(connection).supportsFeature(userID, namespace); } } diff --git a/extensions/src/test/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamManagerTest.java b/extensions/src/test/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamManagerTest.java index 7073b9b17..207325869 100644 --- a/extensions/src/test/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamManagerTest.java +++ b/extensions/src/test/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamManagerTest.java @@ -19,8 +19,10 @@ package org.jivesoftware.smackx.bytestreams.ibb; import static org.junit.Assert.*; import static org.mockito.Mockito.*; +import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.XMPPError; import org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamManager; @@ -55,9 +57,10 @@ public class InBandBytestreamManagerTest { /** * Initialize fields used in the tests. * @throws XMPPException + * @throws SmackException */ @Before - public void setup() throws XMPPException { + public void setup() throws XMPPException, SmackException { // build protocol verifier protocol = new Protocol(); @@ -97,9 +100,11 @@ public class InBandBytestreamManagerTest { * Invoking {@link InBandBytestreamManager#establishSession(String)} should * throw an exception if the given target does not support in-band * bytestream. + * @throws SmackException + * @throws XMPPException */ @Test - public void shouldFailIfTargetDoesNotSupportIBB() { + public void shouldFailIfTargetDoesNotSupportIBB() throws SmackException, XMPPException { InBandBytestreamManager byteStreamManager = InBandBytestreamManager.getByteStreamManager(connection); try { @@ -113,7 +118,7 @@ public class InBandBytestreamManagerTest { fail("exception should be thrown"); } - catch (XMPPException e) { + catch (XMPPErrorException e) { assertEquals(XMPPError.Condition.feature_not_implemented.toString(), e.getXMPPError().getCondition()); } @@ -147,7 +152,7 @@ public class InBandBytestreamManagerTest { } @Test - public void shouldUseConfiguredStanzaType() { + public void shouldUseConfiguredStanzaType() throws SmackException { InBandBytestreamManager byteStreamManager = InBandBytestreamManager.getByteStreamManager(connection); byteStreamManager.setStanza(StanzaType.MESSAGE); diff --git a/extensions/src/test/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamSessionMessageTest.java b/extensions/src/test/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamSessionMessageTest.java index 93078a257..e701f88c3 100644 --- a/extensions/src/test/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamSessionMessageTest.java +++ b/extensions/src/test/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamSessionMessageTest.java @@ -23,6 +23,7 @@ import java.io.InputStream; import java.io.OutputStream; import java.util.Random; +import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.PacketListener; import org.jivesoftware.smack.XMPPException; @@ -73,9 +74,10 @@ public class InBandBytestreamSessionMessageTest { /** * Initialize fields used in the tests. * @throws XMPPException + * @throws SmackException */ @Before - public void setup() throws XMPPException { + public void setup() throws XMPPException, SmackException { // build protocol verifier protocol = new Protocol(); diff --git a/extensions/src/test/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamSessionTest.java b/extensions/src/test/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamSessionTest.java index 32b81bc93..968af9338 100644 --- a/extensions/src/test/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamSessionTest.java +++ b/extensions/src/test/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamSessionTest.java @@ -23,6 +23,7 @@ import java.io.InputStream; import java.io.OutputStream; import java.util.Random; +import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.PacketListener; import org.jivesoftware.smack.XMPPException; @@ -74,9 +75,10 @@ public class InBandBytestreamSessionTest { /** * Initialize fields used in the tests. * @throws XMPPException + * @throws SmackException */ @Before - public void setup() throws XMPPException { + public void setup() throws XMPPException, SmackException { // build protocol verifier protocol = new Protocol(); diff --git a/extensions/src/test/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5ByteStreamManagerTest.java b/extensions/src/test/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5ByteStreamManagerTest.java index 7e6a1b4bc..35fe39901 100644 --- a/extensions/src/test/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5ByteStreamManagerTest.java +++ b/extensions/src/test/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5ByteStreamManagerTest.java @@ -24,8 +24,10 @@ import java.io.InputStream; import java.io.OutputStream; import java.net.ConnectException; +import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.XMPPError; import org.jivesoftware.smack.packet.IQ.Type; @@ -71,9 +73,10 @@ public class Socks5ByteStreamManagerTest { /** * Initialize fields used in the tests. * @throws XMPPException + * @throws SmackException */ @Before - public void setup() throws XMPPException { + public void setup() throws XMPPException, SmackException { // build protocol verifier protocol = new Protocol(); @@ -133,9 +136,10 @@ public class Socks5ByteStreamManagerTest { /** * Invoking {@link Socks5BytestreamManager#establishSession(String)} should throw an exception * if the given target does not support SOCKS5 Bytestream. + * @throws XMPPException */ @Test - public void shouldFailIfTargetDoesNotSupportSocks5() { + public void shouldFailIfTargetDoesNotSupportSocks5() throws XMPPException { Socks5BytestreamManager byteStreamManager = Socks5BytestreamManager.getBytestreamManager(connection); try { @@ -148,7 +152,7 @@ public class Socks5ByteStreamManagerTest { fail("exception should be thrown"); } - catch (XMPPException e) { + catch (SmackException e) { assertTrue(e.getMessage().contains("doesn't support SOCKS5 Bytestream")); } catch (IOException e) { @@ -201,7 +205,7 @@ public class Socks5ByteStreamManagerTest { fail("exception should be thrown"); } - catch (XMPPException e) { + catch (SmackException e) { protocol.verifyAll(); assertTrue(e.getMessage().contains("no SOCKS5 proxies available")); } @@ -264,7 +268,7 @@ public class Socks5ByteStreamManagerTest { fail("exception should be thrown"); } - catch (XMPPException e) { + catch (SmackException e) { protocol.verifyAll(); assertTrue(e.getMessage().contains("no SOCKS5 proxies available")); } @@ -328,7 +332,7 @@ public class Socks5ByteStreamManagerTest { fail("exception should be thrown"); } - catch (XMPPException e) { + catch (SmackException e) { protocol.verifyAll(); assertTrue(e.getMessage().contains("no SOCKS5 proxies available")); } @@ -351,7 +355,7 @@ public class Socks5ByteStreamManagerTest { fail("exception should be thrown"); } - catch (XMPPException e) { + catch (SmackException e) { /* * #verifyAll() tests if the number of requests and responses corresponds and should * fail if the invalid proxy is queried again @@ -446,7 +450,7 @@ public class Socks5ByteStreamManagerTest { fail("exception should be thrown"); } - catch (XMPPException e) { + catch (XMPPErrorException e) { protocol.verifyAll(); assertEquals(xmppError, e.getXMPPError()); } @@ -528,7 +532,7 @@ public class Socks5ByteStreamManagerTest { fail("exception should be thrown"); } - catch (XMPPException e) { + catch (SmackException e) { protocol.verifyAll(); assertTrue(e.getMessage().contains("Remote user responded with unknown host")); } @@ -1024,7 +1028,6 @@ public class Socks5ByteStreamManagerTest { DiscoverInfo proxyInfo1 = Socks5PacketUtils.createDiscoverInfo("proxy2.xmpp-server", initiatorJID); Identity identity1 = new Identity("proxy", "proxy2.xmpp-server", "bytestreams"); - identity1.setType("bytestreams"); proxyInfo1.addIdentity(identity1); // return the SOCKS5 bytestream proxy identity if proxy is queried diff --git a/extensions/src/test/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5ByteStreamRequestTest.java b/extensions/src/test/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5ByteStreamRequestTest.java index eb107f334..3b26282d6 100644 --- a/extensions/src/test/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5ByteStreamRequestTest.java +++ b/extensions/src/test/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5ByteStreamRequestTest.java @@ -23,8 +23,10 @@ import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; +import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.Packet; import org.jivesoftware.smack.packet.XMPPError; @@ -60,9 +62,10 @@ public class Socks5ByteStreamRequestTest { /** * Initialize fields used in the tests. * @throws XMPPException + * @throws SmackException */ @Before - public void setup() throws XMPPException { + public void setup() throws XMPPException, SmackException { // build protocol verifier protocol = new Protocol(); @@ -99,7 +102,7 @@ public class Socks5ByteStreamRequestTest { fail("exception should be thrown"); } - catch (XMPPException e) { + catch (XMPPErrorException e) { assertTrue(e.getMessage().contains("Could not establish socket with any provided host")); } @@ -143,7 +146,7 @@ public class Socks5ByteStreamRequestTest { fail("exception should be thrown"); } - catch (XMPPException e) { + catch (XMPPErrorException e) { assertTrue(e.getMessage().contains("Could not establish socket with any provided host")); } @@ -190,7 +193,7 @@ public class Socks5ByteStreamRequestTest { fail("exception should be thrown"); } - catch (XMPPException e) { + catch (XMPPErrorException e) { assertTrue(e.getMessage().contains( "Could not establish socket with any provided host")); } diff --git a/extensions/src/test/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5ClientForInitiatorTest.java b/extensions/src/test/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5ClientForInitiatorTest.java index 4d686ce80..d0482e5a9 100644 --- a/extensions/src/test/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5ClientForInitiatorTest.java +++ b/extensions/src/test/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5ClientForInitiatorTest.java @@ -22,8 +22,10 @@ import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; +import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.XMPPError; import org.jivesoftware.smack.packet.IQ.Type; @@ -65,9 +67,10 @@ public class Socks5ClientForInitiatorTest { /** * Initialize fields used in the tests. * @throws XMPPException + * @throws SmackException */ @Before - public void setup() throws XMPPException { + public void setup() throws XMPPException, SmackException { // build protocol verifier protocol = new Protocol(); @@ -106,7 +109,7 @@ public class Socks5ClientForInitiatorTest { fail("exception should be thrown"); } - catch (XMPPException e) { + catch (SmackException e) { assertTrue(e.getMessage().contains("target is not connected to SOCKS5 proxy")); protocol.verifyAll(); // assert no XMPP messages were sent } @@ -228,8 +231,8 @@ public class Socks5ClientForInitiatorTest { fail("exception should be thrown"); } - catch (XMPPException e) { - assertTrue(e.getMessage().contains("activating SOCKS5 Bytestream failed")); + catch (XMPPErrorException e) { + assertTrue(XMPPError.Condition.internal_server_error.equals(e.getXMPPError().getCondition())); protocol.verifyAll(); } diff --git a/extensions/src/test/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5ClientTest.java b/extensions/src/test/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5ClientTest.java index f6cf65e79..fcdb189eb 100644 --- a/extensions/src/test/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5ClientTest.java +++ b/extensions/src/test/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5ClientTest.java @@ -23,7 +23,7 @@ import java.io.DataOutputStream; import java.net.ServerSocket; import java.net.Socket; -import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.SmackException; import org.jivesoftware.smackx.bytestreams.socks5.Socks5Client; import org.jivesoftware.smackx.bytestreams.socks5.Socks5Utils; import org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream.StreamHost; @@ -81,9 +81,9 @@ public class Socks5ClientTest { fail("exception should be thrown"); } - catch (XMPPException e) { + catch (SmackException e) { assertTrue(e.getMessage().contains( - "establishing connection to SOCKS5 proxy failed")); + "SOCKS5 negotiation failed")); } catch (Exception e) { fail(e.getMessage()); @@ -138,9 +138,9 @@ public class Socks5ClientTest { fail("exception should be thrown"); } - catch (XMPPException e) { + catch (SmackException e) { assertTrue(e.getMessage().contains( - "establishing connection to SOCKS5 proxy failed")); + "Unsupported SOCKS5 address type")); } catch (Exception e) { fail(e.getMessage()); @@ -201,9 +201,9 @@ public class Socks5ClientTest { fail("exception should be thrown"); } - catch (XMPPException e) { + catch (SmackException e) { assertTrue(e.getMessage().contains( - "establishing connection to SOCKS5 proxy failed")); + "SOCKS5 negotiation failed")); } catch (Exception e) { fail(e.getMessage()); diff --git a/extensions/src/test/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5TestProxy.java b/extensions/src/test/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5TestProxy.java index 62d59d81d..094075bd1 100644 --- a/extensions/src/test/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5TestProxy.java +++ b/extensions/src/test/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5TestProxy.java @@ -27,7 +27,7 @@ import java.net.UnknownHostException; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.SmackException; import org.jivesoftware.smackx.bytestreams.socks5.Socks5Utils; /** @@ -227,17 +227,17 @@ public class Socks5TestProxy { * Negotiates a SOCKS5 connection and stores it on success. * * @param socket connection to the client - * @throws XMPPException if client requests a connection in an unsupported way + * @throws SmackException if client requests a connection in an unsupported way * @throws IOException if a network error occurred */ - private void establishConnection(Socket socket) throws XMPPException, IOException { + private void establishConnection(Socket socket) throws IOException, SmackException { DataOutputStream out = new DataOutputStream(socket.getOutputStream()); DataInputStream in = new DataInputStream(socket.getInputStream()); // first byte is version should be 5 int b = in.read(); if (b != 5) { - throw new XMPPException("Only SOCKS5 supported"); + throw new SmackException("Only SOCKS5 supported"); } // second byte number of authentication methods supported @@ -263,7 +263,7 @@ public class Socks5TestProxy { authMethodSelectionResponse[1] = (byte) 0xFF; // no acceptable methods out.write(authMethodSelectionResponse); out.flush(); - throw new XMPPException("Authentication method not supported"); + throw new SmackException("Authentication method not supported"); } authMethodSelectionResponse[1] = (byte) 0x00; // no-authentication method diff --git a/extensions/src/test/java/org/jivesoftware/smackx/ping/PingTest.java b/extensions/src/test/java/org/jivesoftware/smackx/ping/PingTest.java index e497c31b7..d75cf92db 100644 --- a/extensions/src/test/java/org/jivesoftware/smackx/ping/PingTest.java +++ b/extensions/src/test/java/org/jivesoftware/smackx/ping/PingTest.java @@ -19,8 +19,11 @@ package org.jivesoftware.smackx.ping; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import org.jivesoftware.smack.DummyConnection; +import org.jivesoftware.smack.SmackException; +import org.jivesoftware.smack.SmackException.NoResponseException; import org.jivesoftware.smack.ThreadedDummyConnection; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.Packet; @@ -70,15 +73,18 @@ public class PingTest extends InitExtensions { } @Test - public void checkSendingPing() throws Exception { + public void checkSendingPing() throws InterruptedException { dummyCon = new DummyConnection(); PingManager pinger = PingManager.getInstanceFor(dummyCon); - pinger.ping("test@myserver.com"); + try { + pinger.ping("test@myserver.com"); + } + catch (SmackException e) { + // Ignore the fact the server won't answer for this unit test. + } Packet sentPacket = dummyCon.getSentPacket(); - assertTrue(sentPacket instanceof Ping); - } @Test @@ -95,17 +101,20 @@ public class PingTest extends InitExtensions { /** * DummyConnection will not reply so it will timeout. - * @throws Exception + * @throws SmackException */ @Test - public void checkFailedPingOnTimeout() throws Exception { + public void checkFailedPingOnTimeout() throws SmackException { dummyCon = new DummyConnection(); PingManager pinger = PingManager.getInstanceFor(dummyCon); - boolean pingSuccess = pinger.ping("test@myserver.com"); - - assertFalse(pingSuccess); - + try { + pinger.ping("test@myserver.com"); + } + catch (NoResponseException e) { + return; + } + fail(); } /** @@ -171,13 +180,18 @@ public class PingTest extends InitExtensions { } @Test - public void checkPingToServerTimeout() throws Exception { + public void checkPingToServerTimeout() throws SmackException { DummyConnection con = new DummyConnection(); PingManager pinger = PingManager.getInstanceFor(con); - boolean pingSuccess = pinger.pingMyServer(); - - assertFalse(pingSuccess); + try { + pinger.pingMyServer(); + } + catch (NoResponseException e) { + return; + } + + fail(); } @Test diff --git a/extensions/src/test/java/org/jivesoftware/smackx/pubsub/ConfigureFormTest.java b/extensions/src/test/java/org/jivesoftware/smackx/pubsub/ConfigureFormTest.java index 939ee0a03..9ce1490fc 100644 --- a/extensions/src/test/java/org/jivesoftware/smackx/pubsub/ConfigureFormTest.java +++ b/extensions/src/test/java/org/jivesoftware/smackx/pubsub/ConfigureFormTest.java @@ -19,8 +19,10 @@ package org.jivesoftware.smackx.pubsub; import static org.junit.Assert.assertEquals; import org.jivesoftware.smack.SmackConfiguration; +import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.ThreadedDummyConnection; import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.packet.XMPPError; import org.jivesoftware.smack.packet.XMPPError.Condition; import org.jivesoftware.smackx.disco.packet.DiscoverInfo; @@ -45,7 +47,7 @@ public class ConfigureFormTest } @Test - public void getConfigFormWithInsufficientPriviliges() throws XMPPException + public void getConfigFormWithInsufficientPriviliges() throws XMPPException, SmackException { ThreadedDummyConnection con = new ThreadedDummyConnection(); PubSubManager mgr = new PubSubManager(con); @@ -65,14 +67,14 @@ public class ConfigureFormTest { node.getNodeConfiguration(); } - catch (XMPPException e) + catch (XMPPErrorException e) { Assert.assertEquals(XMPPError.Type.AUTH, e.getXMPPError().getType()); } } - @Test (expected=XMPPException.class) - public void getConfigFormWithTimeout() throws XMPPException + @Test (expected=SmackException.class) + public void getConfigFormWithTimeout() throws XMPPException, SmackException { ThreadedDummyConnection con = new ThreadedDummyConnection(); PubSubManager mgr = new PubSubManager(con); diff --git a/extensions/src/test/java/org/jivesoftware/util/ConnectionUtils.java b/extensions/src/test/java/org/jivesoftware/util/ConnectionUtils.java index d112e614c..fe80a01ae 100644 --- a/extensions/src/test/java/org/jivesoftware/util/ConnectionUtils.java +++ b/extensions/src/test/java/org/jivesoftware/util/ConnectionUtils.java @@ -20,8 +20,9 @@ import static org.mockito.Matchers.*; import static org.mockito.Mockito.*; import org.jivesoftware.smack.PacketCollector; +import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.XMPPConnection; -import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.filter.PacketFilter; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.Packet; @@ -57,10 +58,11 @@ public class ConnectionUtils { * @param initiatorJID the user associated to the XMPP connection * @param xmppServer the XMPP server associated to the XMPP connection * @return a mocked XMPP connection - * @throws XMPPException + * @throws SmackException + * @throws XMPPErrorException */ public static XMPPConnection createMockedConnection(final Protocol protocol, - String initiatorJID, String xmppServer) throws XMPPException { + String initiatorJID, String xmppServer) throws SmackException, XMPPErrorException { // mock XMPP connection XMPPConnection connection = mock(XMPPConnection.class); @@ -105,7 +107,7 @@ public class ConnectionUtils { Packet packet = protocol.getResponses().poll(); if (packet == null) return packet; XMPPError xmppError = packet.getError(); - if (xmppError != null) throw new XMPPException(xmppError); + if (xmppError != null) throw new XMPPErrorException(xmppError); return packet; } }; diff --git a/jingle/src/main/java/org/jivesoftware/smackx/jingle/ContentNegotiator.java b/jingle/src/main/java/org/jivesoftware/smackx/jingle/ContentNegotiator.java index 8cbdf4955..20d3bc872 100644 --- a/jingle/src/main/java/org/jivesoftware/smackx/jingle/ContentNegotiator.java +++ b/jingle/src/main/java/org/jivesoftware/smackx/jingle/ContentNegotiator.java @@ -19,6 +19,7 @@ package org.jivesoftware.smackx.jingle; import java.util.ArrayList; import java.util.List; +import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smackx.jingle.listeners.JingleListener; @@ -56,7 +57,7 @@ public class ContentNegotiator extends JingleNegotiator { transportNegotiators = new ArrayList(); } - public List dispatchIncomingPacket(IQ iq, String id) throws XMPPException { + public List dispatchIncomingPacket(IQ iq, String id) throws XMPPException, SmackException { List responses = new ArrayList(); // First only process IQ packets that contain stanzas that diff --git a/jingle/src/main/java/org/jivesoftware/smackx/jingle/JingleManager.java b/jingle/src/main/java/org/jivesoftware/smackx/jingle/JingleManager.java index 86ba20257..d31cd4e7a 100644 --- a/jingle/src/main/java/org/jivesoftware/smackx/jingle/JingleManager.java +++ b/jingle/src/main/java/org/jivesoftware/smackx/jingle/JingleManager.java @@ -24,6 +24,7 @@ import java.util.logging.Logger; import org.jivesoftware.smack.ConnectionCreationListener; import org.jivesoftware.smack.PacketListener; import org.jivesoftware.smack.RosterListener; +import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.filter.PacketFilter; @@ -44,7 +45,6 @@ import org.jivesoftware.smackx.jingle.nat.TransportCandidate; import org.jivesoftware.smackx.jingle.nat.TransportResolver; import org.jivesoftware.smackx.jingle.packet.Jingle; import org.jivesoftware.smackx.jingle.provider.JingleProvider; -import org.jivesoftware.smackx.disco.packet.DiscoverInfo; /** * Jingle is a session establishment protocol defined in (XEP-0166). @@ -205,8 +205,10 @@ public class JingleManager implements JingleSessionListener { * * @param connection XMPP XMPPConnection to be used * @param jingleMediaManagers an implemeted JingleMediaManager to be used. + * @throws SmackException + * @throws XMPPException */ - public JingleManager(XMPPConnection connection, List jingleMediaManagers) { + public JingleManager(XMPPConnection connection, List jingleMediaManagers) throws XMPPException, SmackException { this.connection = connection; this.jingleMediaManagers = jingleMediaManagers; @@ -307,15 +309,11 @@ public class JingleManager implements JingleSessionListener { * jdoe@example.com * @return a boolean indicating whether the specified user handles Jingle * messages + * @throws SmackException if there was no response from the server. + * @throws XMPPException */ - public static boolean isServiceEnabled(XMPPConnection connection, String userID) { - try { - DiscoverInfo result = ServiceDiscoveryManager.getInstanceFor(connection).discoverInfo(userID); - return result.containsFeature(Jingle.NAMESPACE); - } catch (XMPPException e) { - e.printStackTrace(); - return false; - } + public static boolean isServiceEnabled(XMPPConnection connection, String userID) throws XMPPException, SmackException { + return ServiceDiscoveryManager.getInstanceFor(connection).supportsFeature(userID, Jingle.NAMESPACE); } /** diff --git a/jingle/src/main/java/org/jivesoftware/smackx/jingle/JingleNegotiator.java b/jingle/src/main/java/org/jivesoftware/smackx/jingle/JingleNegotiator.java index 880909d59..732e167ed 100644 --- a/jingle/src/main/java/org/jivesoftware/smackx/jingle/JingleNegotiator.java +++ b/jingle/src/main/java/org/jivesoftware/smackx/jingle/JingleNegotiator.java @@ -20,6 +20,7 @@ import java.util.ArrayList; import java.util.List; import java.util.logging.Logger; +import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.packet.IQ; @@ -232,7 +233,7 @@ public abstract class JingleNegotiator { * @return the new packet to send (either a Jingle or an IQ error). * @throws XMPPException */ - public abstract List dispatchIncomingPacket(IQ iq, String id) throws XMPPException; + public abstract List dispatchIncomingPacket(IQ iq, String id) throws XMPPException, SmackException; public void start() { diff --git a/jingle/src/main/java/org/jivesoftware/smackx/jingle/JingleSession.java b/jingle/src/main/java/org/jivesoftware/smackx/jingle/JingleSession.java index e488e65ad..eedc44a88 100644 --- a/jingle/src/main/java/org/jivesoftware/smackx/jingle/JingleSession.java +++ b/jingle/src/main/java/org/jivesoftware/smackx/jingle/JingleSession.java @@ -25,6 +25,7 @@ import java.util.logging.Logger; import org.jivesoftware.smack.ConnectionListener; import org.jivesoftware.smack.PacketListener; +import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.filter.PacketFilter; @@ -273,8 +274,9 @@ public class JingleSession extends JingleNegotiator implements MediaReceivedList * @param iq * the packet received * @throws XMPPException + * @throws SmackException */ - public synchronized void receivePacketAndRespond(IQ iq) throws XMPPException { + public synchronized void receivePacketAndRespond(IQ iq) throws XMPPException, SmackException { List responses = new ArrayList(); String responseId = null; @@ -340,8 +342,9 @@ public class JingleSession extends JingleNegotiator implements MediaReceivedList * the packet received * @return the new Jingle packet to send. * @throws XMPPException + * @throws SmackException */ - public List dispatchIncomingPacket(IQ iq, String id) throws XMPPException { + public List dispatchIncomingPacket(IQ iq, String id) throws XMPPException, SmackException { List responses = new ArrayList(); IQ response = null; @@ -676,7 +679,7 @@ public class JingleSession extends JingleNegotiator implements MediaReceivedList public void processPacket(Packet packet) { try { receivePacketAndRespond((IQ) packet); - } catch (XMPPException e) { + } catch (Exception e) { e.printStackTrace(); } } @@ -1110,8 +1113,9 @@ public class JingleSession extends JingleNegotiator implements MediaReceivedList * This is the starting point for intitiating a new session. * * @throws IllegalStateException + * @throws SmackException */ - public void startOutgoing() throws IllegalStateException { + public void startOutgoing() throws IllegalStateException, SmackException { updatePacketListener(); setSessionState(JingleSessionStatePending.getInstance()); diff --git a/jingle/src/main/java/org/jivesoftware/smackx/jingle/JingleSessionRequest.java b/jingle/src/main/java/org/jivesoftware/smackx/jingle/JingleSessionRequest.java index 6b8e72580..e04009218 100644 --- a/jingle/src/main/java/org/jivesoftware/smackx/jingle/JingleSessionRequest.java +++ b/jingle/src/main/java/org/jivesoftware/smackx/jingle/JingleSessionRequest.java @@ -19,6 +19,7 @@ package org.jivesoftware.smackx.jingle; import java.util.logging.Level; import java.util.logging.Logger; +import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smackx.jingle.packet.Jingle; @@ -105,8 +106,9 @@ public class JingleSessionRequest { * * @return Returns the IncomingJingleSession on which the * negotiation can be carried out. + * @throws SmackException */ - public synchronized JingleSession accept() throws XMPPException { + public synchronized JingleSession accept() throws XMPPException, SmackException { JingleSession session = null; synchronized (manager) { session = manager.createIncomingJingleSession(this); diff --git a/jingle/src/main/java/org/jivesoftware/smackx/jingle/JingleSessionState.java b/jingle/src/main/java/org/jivesoftware/smackx/jingle/JingleSessionState.java index 9adddad0e..df205ce58 100644 --- a/jingle/src/main/java/org/jivesoftware/smackx/jingle/JingleSessionState.java +++ b/jingle/src/main/java/org/jivesoftware/smackx/jingle/JingleSessionState.java @@ -16,6 +16,7 @@ */ package org.jivesoftware.smackx.jingle; +import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smackx.jingle.packet.Jingle; @@ -54,7 +55,7 @@ public abstract class JingleSessionState { * Process an incoming Jingle Packet. * When you look at the GoF State pattern this method roughly corresponds to example on p310: ProcessOctect(). */ - public abstract IQ processJingle(JingleSession session, Jingle jingle, JingleActionEnum action); + public abstract IQ processJingle(JingleSession session, Jingle jingle, JingleActionEnum action) throws SmackException; /** * For debugging just emit the short name of the class. diff --git a/jingle/src/main/java/org/jivesoftware/smackx/jingle/JingleSessionStateUnknown.java b/jingle/src/main/java/org/jivesoftware/smackx/jingle/JingleSessionStateUnknown.java index 3f5246603..11c425a90 100644 --- a/jingle/src/main/java/org/jivesoftware/smackx/jingle/JingleSessionStateUnknown.java +++ b/jingle/src/main/java/org/jivesoftware/smackx/jingle/JingleSessionStateUnknown.java @@ -16,6 +16,7 @@ */ package org.jivesoftware.smackx.jingle; +import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smackx.jingle.media.JingleMediaManager; @@ -62,7 +63,7 @@ public class JingleSessionStateUnknown extends JingleSessionState { } - public IQ processJingle(JingleSession session, Jingle jingle, JingleActionEnum action) { + public IQ processJingle(JingleSession session, Jingle jingle, JingleActionEnum action) throws SmackException { IQ response = null; switch (action) { @@ -86,9 +87,10 @@ public class JingleSessionStateUnknown extends JingleSessionState { /** * In the UNKNOWN state we received a action. * This method processes that action. + * @throws SmackException */ - private IQ receiveSessionInitiateAction(JingleSession session, Jingle inJingle) { + private IQ receiveSessionInitiateAction(JingleSession session, Jingle inJingle) throws SmackException { IQ response = null; boolean shouldAck = true; diff --git a/jingle/src/main/java/org/jivesoftware/smackx/jingle/nat/BridgedResolver.java b/jingle/src/main/java/org/jivesoftware/smackx/jingle/nat/BridgedResolver.java index d0b7891de..4cc1e5e6e 100644 --- a/jingle/src/main/java/org/jivesoftware/smackx/jingle/nat/BridgedResolver.java +++ b/jingle/src/main/java/org/jivesoftware/smackx/jingle/nat/BridgedResolver.java @@ -16,8 +16,10 @@ */ package org.jivesoftware.smackx.jingle.nat; +import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smackx.jingle.JingleSession; import java.net.Inet6Address; @@ -94,13 +96,13 @@ public class BridgedResolver extends TransportResolver { setResolveEnd(); } - public void initialize() throws XMPPException { + public void initialize() throws SmackException, XMPPErrorException { clearCandidates(); if (!RTPBridge.serviceAvailable(connection)) { setInitialized(); - throw new XMPPException("No RTP Bridge service available"); + throw new SmackException("No RTP Bridge service available"); } setInitialized(); diff --git a/jingle/src/main/java/org/jivesoftware/smackx/jingle/nat/ICEResolver.java b/jingle/src/main/java/org/jivesoftware/smackx/jingle/nat/ICEResolver.java index f0c1e269f..5df366122 100644 --- a/jingle/src/main/java/org/jivesoftware/smackx/jingle/nat/ICEResolver.java +++ b/jingle/src/main/java/org/jivesoftware/smackx/jingle/nat/ICEResolver.java @@ -26,6 +26,7 @@ import java.util.Map; import java.util.Random; import java.util.logging.Logger; +import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smackx.jingle.JingleSession; @@ -89,8 +90,9 @@ public class ICEResolver extends TransportResolver { /** * Resolve the IP and obtain a valid transport method. + * @throws SmackException */ - public synchronized void resolve(JingleSession session) throws XMPPException { + public synchronized void resolve(JingleSession session) throws XMPPException, SmackException { this.setResolveInit(); for (TransportCandidate candidate : this.getCandidatesList()) { diff --git a/jingle/src/main/java/org/jivesoftware/smackx/jingle/nat/ICETransportManager.java b/jingle/src/main/java/org/jivesoftware/smackx/jingle/nat/ICETransportManager.java index a89c490d0..56703e3c0 100644 --- a/jingle/src/main/java/org/jivesoftware/smackx/jingle/nat/ICETransportManager.java +++ b/jingle/src/main/java/org/jivesoftware/smackx/jingle/nat/ICETransportManager.java @@ -16,6 +16,7 @@ */ package org.jivesoftware.smackx.jingle.nat; +import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smackx.jingle.JingleSession; @@ -32,12 +33,12 @@ public class ICETransportManager extends JingleTransportManager implements Jingl try { iceResolver.initializeAndWait(); } - catch (XMPPException e) { + catch (Exception e) { e.printStackTrace(); } } - protected TransportResolver createResolver(JingleSession session) { + protected TransportResolver createResolver(JingleSession session) throws SmackException { try { iceResolver.resolve(session); } diff --git a/jingle/src/main/java/org/jivesoftware/smackx/jingle/nat/JingleTransportManager.java b/jingle/src/main/java/org/jivesoftware/smackx/jingle/nat/JingleTransportManager.java index 1d0fbd787..75a75bc2d 100644 --- a/jingle/src/main/java/org/jivesoftware/smackx/jingle/nat/JingleTransportManager.java +++ b/jingle/src/main/java/org/jivesoftware/smackx/jingle/nat/JingleTransportManager.java @@ -16,6 +16,7 @@ */ package org.jivesoftware.smackx.jingle.nat; +import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smackx.jingle.JingleSession; @@ -51,7 +52,7 @@ public abstract class JingleTransportManager { * * @return the TransportResolver to be used */ - public TransportResolver getResolver(JingleSession session) throws XMPPException { + public TransportResolver getResolver(JingleSession session) throws XMPPException, SmackException { TransportResolver resolver = createResolver(session); if (resolver == null) { resolver = new BasicResolver(); @@ -66,6 +67,6 @@ public abstract class JingleTransportManager { * * @return the TransportResolver */ - protected abstract TransportResolver createResolver(JingleSession session); + protected abstract TransportResolver createResolver(JingleSession session) throws SmackException; } diff --git a/jingle/src/main/java/org/jivesoftware/smackx/jingle/nat/RTPBridge.java b/jingle/src/main/java/org/jivesoftware/smackx/jingle/nat/RTPBridge.java index 53c6f39c8..45f26a2cb 100644 --- a/jingle/src/main/java/org/jivesoftware/smackx/jingle/nat/RTPBridge.java +++ b/jingle/src/main/java/org/jivesoftware/smackx/jingle/nat/RTPBridge.java @@ -24,9 +24,10 @@ import java.util.Enumeration; import java.util.Iterator; import java.util.logging.Logger; +import org.jivesoftware.smack.SmackException.NoResponseException; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.PacketCollector; -import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.provider.IQProvider; import org.jivesoftware.smack.provider.ProviderManager; @@ -407,8 +408,11 @@ public class RTPBridge extends IQ { * * @param connection * @return true if the server supports the RTPBridge service + * @throws XMPPErrorException + * @throws NoResponseException */ - public static boolean serviceAvailable(XMPPConnection connection) { + public static boolean serviceAvailable(XMPPConnection connection) throws NoResponseException, + XMPPErrorException { if (!connection.isConnected()) { return false; @@ -418,7 +422,6 @@ public class RTPBridge extends IQ { ServiceDiscoveryManager disco = ServiceDiscoveryManager .getInstanceFor(connection); - try { // DiscoverItems items = disco.discoverItems(connection.getServiceName()); // Iterator iter = items.getItems(); // while (iter.hasNext()) { @@ -428,17 +431,13 @@ public class RTPBridge extends IQ { // } // } - DiscoverInfo discoInfo = disco.discoverInfo(connection.getServiceName()); - Iterator iter = discoInfo.getIdentities(); - while (iter.hasNext()) { - DiscoverInfo.Identity identity = iter.next(); - if ((identity.getName() != null) && (identity.getName().startsWith("rtpbridge"))) { - return true; - } + DiscoverInfo discoInfo = disco.discoverInfo(connection.getServiceName()); + Iterator iter = discoInfo.getIdentities(); + while (iter.hasNext()) { + DiscoverInfo.Identity identity = iter.next(); + if ((identity.getName() != null) && (identity.getName().startsWith("rtpbridge"))) { + return true; } - } - catch (XMPPException e) { - e.printStackTrace(); } return false; diff --git a/jingle/src/main/java/org/jivesoftware/smackx/jingle/nat/STUN.java b/jingle/src/main/java/org/jivesoftware/smackx/jingle/nat/STUN.java index 823a37fa6..3825edf2a 100644 --- a/jingle/src/main/java/org/jivesoftware/smackx/jingle/nat/STUN.java +++ b/jingle/src/main/java/org/jivesoftware/smackx/jingle/nat/STUN.java @@ -19,9 +19,9 @@ package org.jivesoftware.smackx.jingle.nat; import java.util.ArrayList; import java.util.Iterator; import java.util.List; -import java.util.logging.Level; import java.util.logging.Logger; +import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.PacketCollector; import org.jivesoftware.smack.XMPPException; @@ -206,8 +206,10 @@ public class STUN extends IQ { * * @param connection the connection * @return true if the server support STUN + * @throws SmackException + * @throws XMPPException */ - public static boolean serviceAvailable(XMPPConnection connection) { + public static boolean serviceAvailable(XMPPConnection connection) throws XMPPException, SmackException { if (!connection.isConnected()) { return false; @@ -215,31 +217,26 @@ public class STUN extends IQ { LOGGER.fine("Service listing"); - ServiceDiscoveryManager disco = ServiceDiscoveryManager - .getInstanceFor(connection); - try { - DiscoverItems items = disco.discoverItems(connection.getServiceName()); + ServiceDiscoveryManager disco = ServiceDiscoveryManager.getInstanceFor(connection); + DiscoverItems items = disco.discoverItems(connection.getServiceName()); - Iterator iter = items.getItems(); - while (iter.hasNext()) { - DiscoverItems.Item item = iter.next(); - DiscoverInfo info = disco.discoverInfo(item.getEntityID()); - - Iterator iter2 = info.getIdentities(); - while (iter2.hasNext()) { - DiscoverInfo.Identity identity = iter2.next(); - if (identity.getCategory().equals("proxy") && identity.getType().equals("stun")) - if (info.containsFeature(NAMESPACE)) - return true; - } - - LOGGER.fine(item.getName()+"-"+info.getType()); + Iterator iter = items.getItems(); + while (iter.hasNext()) { + DiscoverItems.Item item = iter.next(); + DiscoverInfo info = disco.discoverInfo(item.getEntityID()); + Iterator iter2 = info.getIdentities(); + while (iter2.hasNext()) { + DiscoverInfo.Identity identity = iter2.next(); + if (identity.getCategory().equals("proxy") && identity.getType().equals("stun")) + if (info.containsFeature(NAMESPACE)) + return true; } + + LOGGER.fine(item.getName() + "-" + info.getType()); + } - catch (XMPPException e) { - LOGGER.log(Level.SEVERE, "serviceAvailable", e); - } + return false; } diff --git a/jingle/src/main/java/org/jivesoftware/smackx/jingle/nat/STUNTransportManager.java b/jingle/src/main/java/org/jivesoftware/smackx/jingle/nat/STUNTransportManager.java index 4b902b911..d0d1a275f 100644 --- a/jingle/src/main/java/org/jivesoftware/smackx/jingle/nat/STUNTransportManager.java +++ b/jingle/src/main/java/org/jivesoftware/smackx/jingle/nat/STUNTransportManager.java @@ -32,7 +32,7 @@ public class STUNTransportManager extends JingleTransportManager { }; try { stunResolver.initializeAndWait(); - } catch (XMPPException e) { + } catch (Exception e) { e.printStackTrace(); } } diff --git a/jingle/src/main/java/org/jivesoftware/smackx/jingle/nat/TransportNegotiator.java b/jingle/src/main/java/org/jivesoftware/smackx/jingle/nat/TransportNegotiator.java index 77c73a8bf..b6a17cfaa 100644 --- a/jingle/src/main/java/org/jivesoftware/smackx/jingle/nat/TransportNegotiator.java +++ b/jingle/src/main/java/org/jivesoftware/smackx/jingle/nat/TransportNegotiator.java @@ -23,6 +23,7 @@ import java.util.Iterator; import java.util.List; import java.util.logging.Logger; +import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smackx.jingle.ContentNegotiator; @@ -160,7 +161,7 @@ public abstract class TransportNegotiator extends JingleNegotiator { try { sendTransportCandidatesOffer(); setNegotiatorState(JingleNegotiatorState.PENDING); - } catch (XMPPException e) { + } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } @@ -528,8 +529,9 @@ public abstract class TransportNegotiator extends JingleNegotiator { * Create a Jingle packet where we announce our transport candidates. * * @throws XMPPException + * @throws SmackException */ - private void sendTransportCandidatesOffer() throws XMPPException { + private void sendTransportCandidatesOffer() throws XMPPException, SmackException { List notOffered = resolver.getCandidatesList(); notOffered.removeAll(offeredCandidates); @@ -572,8 +574,9 @@ public abstract class TransportNegotiator extends JingleNegotiator { * @param iq the packet received * @return the new Jingle packet to send. * @throws XMPPException + * @throws SmackException */ - public final List dispatchIncomingPacket(IQ iq, String id) throws XMPPException { + public final List dispatchIncomingPacket(IQ iq, String id) throws XMPPException, SmackException { List responses = new ArrayList(); IQ response = null; @@ -641,8 +644,9 @@ public abstract class TransportNegotiator extends JingleNegotiator { * * @return an IQ packet * @throws XMPPException + * @throws SmackException */ - private Jingle receiveResult(IQ iq) throws XMPPException { + private Jingle receiveResult(IQ iq) throws XMPPException, SmackException { Jingle response = null; sendTransportCandidatesOffer(); @@ -655,8 +659,9 @@ public abstract class TransportNegotiator extends JingleNegotiator { * @param jingle * @param jingleTransport * @return the iq + * @throws SmackException */ - private IQ receiveSessionInitiateAction(Jingle jingle) throws XMPPException { + private IQ receiveSessionInitiateAction(Jingle jingle) throws XMPPException, SmackException { IQ response = null; // Parse the Jingle and get any proposed transport candidates diff --git a/jingle/src/main/java/org/jivesoftware/smackx/jingle/nat/TransportResolver.java b/jingle/src/main/java/org/jivesoftware/smackx/jingle/nat/TransportResolver.java index 61c5126fc..42631614f 100644 --- a/jingle/src/main/java/org/jivesoftware/smackx/jingle/nat/TransportResolver.java +++ b/jingle/src/main/java/org/jivesoftware/smackx/jingle/nat/TransportResolver.java @@ -24,6 +24,7 @@ import java.util.Iterator; import java.util.List; import java.util.logging.Logger; +import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smackx.jingle.JingleSession; @@ -89,12 +90,12 @@ public abstract class TransportResolver { /** * Initialize the Resolver */ - public abstract void initialize() throws XMPPException; + public abstract void initialize() throws XMPPException, SmackException; /** * Start a the resolution. */ - public abstract void resolve(JingleSession session) throws XMPPException; + public abstract void resolve(JingleSession session) throws XMPPException, SmackException; /** * Clear the list of candidates and start a new resolution process. @@ -352,8 +353,9 @@ public abstract class TransportResolver { /** * Initialize Transport Resolver and wait until it is complete unitialized. + * @throws SmackException */ - public void initializeAndWait() throws XMPPException { + public void initializeAndWait() throws XMPPException, SmackException { this.initialize(); try { LOGGER.fine("Initializing transport resolver..."); diff --git a/jingle/src/main/java/org/jivesoftware/smackx/jingle/provider/JingleProvider.java b/jingle/src/main/java/org/jivesoftware/smackx/jingle/provider/JingleProvider.java index aa48a5885..1bda6221f 100644 --- a/jingle/src/main/java/org/jivesoftware/smackx/jingle/provider/JingleProvider.java +++ b/jingle/src/main/java/org/jivesoftware/smackx/jingle/provider/JingleProvider.java @@ -17,7 +17,7 @@ package org.jivesoftware.smackx.jingle.provider; -import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.provider.IQProvider; import org.jivesoftware.smackx.jingle.JingleActionEnum; @@ -101,12 +101,12 @@ public class JingleProvider implements IQProvider { } else if (namespace.equals(JingleTransport.Ice.NAMESPACE)) { currentContent.addJingleTransport((JingleTransport) jtpIce.parseExtension(parser)); } else { - throw new XMPPException("Unknown transport namespace \"" + namespace + "\" in Jingle packet."); + throw new SmackException("Unknown transport namespace \"" + namespace + "\" in Jingle packet."); } } else if (namespace.equals(JingleContentInfo.Audio.NAMESPACE)) { jingle.setContentInfo((JingleContentInfo) jmipAudio.parseExtension(parser)); } else { - throw new XMPPException("Unknown combination of namespace \"" + namespace + "\" and element name \"" + throw new SmackException("Unknown combination of namespace \"" + namespace + "\" and element name \"" + elementName + "\" in Jingle packet."); } diff --git a/legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/Agent.java b/legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/Agent.java index 0198e66bf..4b87a91c0 100644 --- a/legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/Agent.java +++ b/legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/Agent.java @@ -19,8 +19,9 @@ package org.jivesoftware.smackx.workgroup.agent; import org.jivesoftware.smackx.workgroup.packet.AgentInfo; import org.jivesoftware.smackx.workgroup.packet.AgentWorkgroups; +import org.jivesoftware.smack.SmackException.NoResponseException; import org.jivesoftware.smack.XMPPConnection; -import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.packet.IQ; import java.util.Collection; @@ -34,7 +35,7 @@ public class Agent { private XMPPConnection connection; private String workgroupJID; - public static Collection getWorkgroups(String serviceJID, String agentJID, XMPPConnection connection) throws XMPPException { + public static Collection getWorkgroups(String serviceJID, String agentJID, XMPPConnection connection) throws NoResponseException, XMPPErrorException { AgentWorkgroups request = new AgentWorkgroups(agentJID); request.setTo(serviceJID); AgentWorkgroups response = (AgentWorkgroups) connection.createPacketCollectorAndSend(request).nextResultOrThrow(); @@ -62,8 +63,10 @@ public class Agent { * Return the agents name. * * @return - the agents name. + * @throws XMPPErrorException + * @throws NoResponseException */ - public String getName() throws XMPPException { + public String getName() throws NoResponseException, XMPPErrorException { AgentInfo agentInfo = new AgentInfo(); agentInfo.setType(IQ.Type.GET); agentInfo.setTo(workgroupJID); @@ -79,10 +82,10 @@ public class Agent { * error code. * * @param newName the new name of the agent. - * @throws XMPPException if the agent is not allowed to change his name or no response was - * obtained from the server. + * @throws XMPPErrorException + * @throws NoResponseException */ - public void setName(String newName) throws XMPPException { + public void setName(String newName) throws NoResponseException, XMPPErrorException { AgentInfo agentInfo = new AgentInfo(); agentInfo.setType(IQ.Type.SET); agentInfo.setTo(workgroupJID); diff --git a/legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/AgentSession.java b/legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/AgentSession.java index 3c768f72e..2b0f7628f 100644 --- a/legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/AgentSession.java +++ b/legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/AgentSession.java @@ -17,6 +17,7 @@ package org.jivesoftware.smackx.workgroup.agent; + import org.jivesoftware.smackx.muc.packet.MUCUser; import org.jivesoftware.smackx.search.ReportedData; import org.jivesoftware.smackx.workgroup.MetaData; @@ -33,6 +34,8 @@ import org.jivesoftware.smackx.workgroup.settings.GenericSettings; import org.jivesoftware.smackx.workgroup.settings.SearchSettings; import org.jivesoftware.smackx.xdata.Form; import org.jivesoftware.smack.*; +import org.jivesoftware.smack.SmackException.NoResponseException; +import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.filter.*; import org.jivesoftware.smack.packet.*; import org.jivesoftware.smack.util.StringUtils; @@ -198,8 +201,9 @@ public class AgentSession { * @param key the meta data key * @param val the non-null meta data value * @throws XMPPException if an exception occurs. + * @throws SmackException */ - public void setMetaData(String key, String val) throws XMPPException { + public void setMetaData(String key, String val) throws XMPPException, SmackException { synchronized (this.metaData) { List oldVals = metaData.get(key); @@ -217,8 +221,9 @@ public class AgentSession { * * @param key the meta data key. * @throws XMPPException if an exception occurs. + * @throws SmackException */ - public void removeMetaData(String key) throws XMPPException { + public void removeMetaData(String key) throws XMPPException, SmackException { synchronized (this.metaData) { List oldVal = metaData.remove(key); @@ -246,8 +251,10 @@ public class AgentSession { * * @param online true to set the agent as online with the workgroup. * @throws XMPPException if an error occurs setting the online status. + * @throws SmackException assertEquals(SmackException.Type.NO_RESPONSE_FROM_SERVER, e.getType()); + return; */ - public void setOnline(boolean online) throws XMPPException { + public void setOnline(boolean online) throws XMPPException, SmackException { // If the online status hasn't changed, do nothing. if (this.online == online) { return; @@ -305,9 +312,10 @@ public class AgentSession { * @param presenceMode the presence mode of the agent. * @param maxChats the maximum number of chats the agent is willing to accept. * @throws XMPPException if an error occurs setting the agent status. + * @throws SmackException * @throws IllegalStateException if the agent is not online with the workgroup. */ - public void setStatus(Presence.Mode presenceMode, int maxChats) throws XMPPException { + public void setStatus(Presence.Mode presenceMode, int maxChats) throws XMPPException, SmackException { setStatus(presenceMode, maxChats, null); } @@ -330,11 +338,12 @@ public class AgentSession { * @param presenceMode the presence mode of the agent. * @param maxChats the maximum number of chats the agent is willing to accept. * @param status sets the status message of the presence update. - * @throws XMPPException if an error occurs setting the agent status. + * @throws XMPPErrorException + * @throws NoResponseException * @throws IllegalStateException if the agent is not online with the workgroup. */ public void setStatus(Presence.Mode presenceMode, int maxChats, String status) - throws XMPPException { + throws NoResponseException, XMPPErrorException { if (!online) { throw new IllegalStateException("Cannot set status when the agent is not online."); } @@ -354,12 +363,14 @@ public class AgentSession { } // Send information about max chats and current chats as a packet extension. DefaultPacketExtension agentStatus = new DefaultPacketExtension(AgentStatus.ELEMENT_NAME, - AgentStatus.NAMESPACE); + AgentStatus.NAMESPACE); agentStatus.setValue("max-chats", "" + maxChats); presence.addExtension(agentStatus); presence.addExtension(new MetaData(this.metaData)); - PacketCollector collector = this.connection.createPacketCollector(new AndFilter(new PacketTypeFilter(Presence.class), FromMatchesFilter.create(workgroupJID))); + PacketCollector collector = this.connection.createPacketCollector(new AndFilter( + new PacketTypeFilter(Presence.class), + FromMatchesFilter.create(workgroupJID))); this.connection.sendPacket(presence); @@ -379,10 +390,11 @@ public class AgentSession { * * @param presenceMode the presence mode of the agent. * @param status sets the status message of the presence update. - * @throws XMPPException if an error occurs setting the agent status. + * @throws XMPPErrorException + * @throws NoResponseException * @throws IllegalStateException if the agent is not online with the workgroup. */ - public void setStatus(Presence.Mode presenceMode, String status) throws XMPPException { + public void setStatus(Presence.Mode presenceMode, String status) throws NoResponseException, XMPPErrorException { if (!online) { throw new IllegalStateException("Cannot set status when the agent is not online."); } @@ -433,8 +445,9 @@ public class AgentSession { * @param userID the id of the user to get his conversations. * @return the transcripts of a given user. * @throws XMPPException if an error occurs while getting the information. + * @throws SmackException */ - public Transcripts getTranscripts(String userID) throws XMPPException { + public Transcripts getTranscripts(String userID) throws XMPPException, SmackException { return transcriptManager.getTranscripts(workgroupJID, userID); } @@ -444,8 +457,9 @@ public class AgentSession { * @param sessionID the id of the session to get the full transcript. * @return the full conversation transcript of a given session. * @throws XMPPException if an error occurs while getting the information. + * @throws SmackException */ - public Transcript getTranscript(String sessionID) throws XMPPException { + public Transcript getTranscript(String sessionID) throws XMPPException, SmackException { return transcriptManager.getTranscript(workgroupJID, sessionID); } @@ -456,8 +470,9 @@ public class AgentSession { * * @return the Form to use for searching transcripts. * @throws XMPPException if an error occurs while sending the request to the server. + * @throws SmackException */ - public Form getTranscriptSearchForm() throws XMPPException { + public Form getTranscriptSearchForm() throws XMPPException, SmackException { return transcriptSearchManager.getSearchForm(StringUtils.parseServer(workgroupJID)); } @@ -468,9 +483,10 @@ public class AgentSession { * * @param completedForm the filled out search form. * @return the result of the transcript search. - * @throws XMPPException if an error occurs while submiting the search to the server. + * @throws SmackException + * @throws XMPPException */ - public ReportedData searchTranscripts(Form completedForm) throws XMPPException { + public ReportedData searchTranscripts(Form completedForm) throws XMPPException, SmackException { return transcriptSearchManager.submitSearch(StringUtils.parseServer(workgroupJID), completedForm); } @@ -482,9 +498,10 @@ public class AgentSession { * * @param roomID the room to get information about its occupants. * @return information about the occupants of the specified room. - * @throws XMPPException if an error occurs while getting information from the server. + * @throws XMPPErrorException + * @throws NoResponseException */ - public OccupantsInfo getOccupantsInfo(String roomID) throws XMPPException { + public OccupantsInfo getOccupantsInfo(String roomID) throws NoResponseException, XMPPErrorException { OccupantsInfo request = new OccupantsInfo(roomID); request.setType(IQ.Type.GET); request.setTo(workgroupJID); @@ -758,9 +775,10 @@ public class AgentSession { * * @param sessionID the session id of a Chat Session. * @param note the chat note to add. - * @throws XMPPException is thrown if an error occurs while adding the note. + * @throws XMPPErrorException + * @throws NoResponseException */ - public void setNote(String sessionID, String note) throws XMPPException { + public void setNote(String sessionID, String note) throws NoResponseException, XMPPErrorException { note = ChatNotes.replace(note, "\n", "\\n"); note = StringUtils.escapeForXML(note); @@ -777,9 +795,10 @@ public class AgentSession { * * @param sessionID the sessionID of the chat session. * @return the ChatNote associated with a given chat session. - * @throws XMPPException if an error occurs while retrieving the ChatNote. + * @throws XMPPErrorException if an error occurs while retrieving the ChatNote. + * @throws NoResponseException */ - public ChatNotes getNote(String sessionID) throws XMPPException { + public ChatNotes getNote(String sessionID) throws NoResponseException, XMPPErrorException { ChatNotes request = new ChatNotes(); request.setType(IQ.Type.GET); request.setTo(workgroupJID); @@ -819,9 +838,10 @@ public class AgentSession { * Asks the workgroup for it's Search Settings. * * @return SearchSettings the search settings for this workgroup. - * @throws XMPPException if an error occurs while getting information from the server. + * @throws XMPPErrorException + * @throws NoResponseException */ - public SearchSettings getSearchSettings() throws XMPPException { + public SearchSettings getSearchSettings() throws NoResponseException, XMPPErrorException { SearchSettings request = new SearchSettings(); request.setType(IQ.Type.GET); request.setTo(workgroupJID); @@ -835,9 +855,10 @@ public class AgentSession { * * @param global true to retrieve global macros, otherwise false for personal macros. * @return MacroGroup the root macro group. - * @throws XMPPException if an error occurs while getting information from the server. + * @throws XMPPErrorException if an error occurs while getting information from the server. + * @throws NoResponseException */ - public MacroGroup getMacros(boolean global) throws XMPPException { + public MacroGroup getMacros(boolean global) throws NoResponseException, XMPPErrorException { Macros request = new Macros(); request.setType(IQ.Type.GET); request.setTo(workgroupJID); @@ -851,9 +872,10 @@ public class AgentSession { * Persists the Personal Macro for an agent. * * @param group the macro group to save. - * @throws XMPPException if an error occurs while getting information from the server. + * @throws XMPPErrorException + * @throws NoResponseException */ - public void saveMacros(MacroGroup group) throws XMPPException { + public void saveMacros(MacroGroup group) throws NoResponseException, XMPPErrorException { Macros request = new Macros(); request.setType(IQ.Type.SET); request.setTo(workgroupJID); @@ -904,11 +926,12 @@ public class AgentSession { * @param invitee JID of entity that will get the invitation. * @param sessionID ID of the support session that the invitee is being invited. * @param reason the reason of the invitation. - * @throws XMPPException if the sender of the invitation is not an agent or the service failed to process + * @throws XMPPErrorException if the sender of the invitation is not an agent or the service failed to process * the request. + * @throws NoResponseException */ - public void sendRoomInvitation(RoomInvitation.Type type, String invitee, String sessionID, String reason) - throws XMPPException { + public void sendRoomInvitation(RoomInvitation.Type type, String invitee, String sessionID, String reason) throws NoResponseException, XMPPErrorException + { final RoomInvitation invitation = new RoomInvitation(type, invitee, sessionID, reason); IQ iq = new IQ() { @@ -944,11 +967,12 @@ public class AgentSession { * @param invitee JID of entity that will get the invitation. * @param sessionID ID of the support session that the invitee is being invited. * @param reason the reason of the invitation. - * @throws XMPPException if the sender of the invitation is not an agent or the service failed to process + * @throws XMPPErrorException if the sender of the invitation is not an agent or the service failed to process * the request. + * @throws NoResponseException */ - public void sendRoomTransfer(RoomTransfer.Type type, String invitee, String sessionID, String reason) - throws XMPPException { + public void sendRoomTransfer(RoomTransfer.Type type, String invitee, String sessionID, String reason) throws NoResponseException, XMPPErrorException + { final RoomTransfer transfer = new RoomTransfer(type, invitee, sessionID, reason); IQ iq = new IQ() { @@ -968,10 +992,11 @@ public class AgentSession { * * @param con the XMPPConnection to use. * @param query an optional query object used to tell the server what metadata to retrieve. This can be null. - * @throws XMPPException if an error occurs while sending the request to the server. * @return the settings for the workgroup. + * @throws XMPPErrorException if an error occurs while sending the request to the server. + * @throws NoResponseException */ - public GenericSettings getGenericSettings(XMPPConnection con, String query) throws XMPPException { + public GenericSettings getGenericSettings(XMPPConnection con, String query) throws NoResponseException, XMPPErrorException { GenericSettings setting = new GenericSettings(); setting.setType(IQ.Type.GET); setting.setTo(workgroupJID); @@ -981,7 +1006,7 @@ public class AgentSession { return response; } - public boolean hasMonitorPrivileges(XMPPConnection con) throws XMPPException { + public boolean hasMonitorPrivileges(XMPPConnection con) throws NoResponseException, XMPPErrorException { MonitorPacket request = new MonitorPacket(); request.setType(IQ.Type.GET); request.setTo(workgroupJID); @@ -990,7 +1015,7 @@ public class AgentSession { return response.isMonitor(); } - public void makeRoomOwner(XMPPConnection con, String sessionID) throws XMPPException { + public void makeRoomOwner(XMPPConnection con, String sessionID) throws NoResponseException, XMPPErrorException { MonitorPacket request = new MonitorPacket(); request.setType(IQ.Type.SET); request.setTo(workgroupJID); diff --git a/legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/TranscriptManager.java b/legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/TranscriptManager.java index f07764ca4..ed1c2f291 100644 --- a/legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/TranscriptManager.java +++ b/legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/TranscriptManager.java @@ -19,8 +19,9 @@ package org.jivesoftware.smackx.workgroup.agent; import org.jivesoftware.smackx.workgroup.packet.Transcript; import org.jivesoftware.smackx.workgroup.packet.Transcripts; +import org.jivesoftware.smack.SmackException.NoResponseException; import org.jivesoftware.smack.XMPPConnection; -import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.XMPPException.XMPPErrorException; /** * A TranscriptManager helps to retrieve the full conversation transcript of a given session @@ -42,9 +43,10 @@ public class TranscriptManager { * @param sessionID the id of the session to get the full transcript. * @param workgroupJID the JID of the workgroup that will process the request. * @return the full conversation transcript of a given session. - * @throws XMPPException if an error occurs while getting the information. + * @throws XMPPErrorException + * @throws NoResponseException */ - public Transcript getTranscript(String workgroupJID, String sessionID) throws XMPPException { + public Transcript getTranscript(String workgroupJID, String sessionID) throws NoResponseException, XMPPErrorException { Transcript request = new Transcript(sessionID); request.setTo(workgroupJID); Transcript response = (Transcript) connection.createPacketCollectorAndSend(request).nextResultOrThrow(); @@ -58,9 +60,10 @@ public class TranscriptManager { * @param userID the id of the user to get his conversations. * @param workgroupJID the JID of the workgroup that will process the request. * @return the transcripts of a given user. - * @throws XMPPException if an error occurs while getting the information. + * @throws XMPPErrorException + * @throws NoResponseException */ - public Transcripts getTranscripts(String workgroupJID, String userID) throws XMPPException { + public Transcripts getTranscripts(String workgroupJID, String userID) throws NoResponseException, XMPPErrorException { Transcripts request = new Transcripts(userID); request.setTo(workgroupJID); Transcripts response = (Transcripts) connection.createPacketCollectorAndSend(request).nextResultOrThrow(); diff --git a/legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/TranscriptSearchManager.java b/legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/TranscriptSearchManager.java index 05750f294..1c2c636d6 100644 --- a/legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/TranscriptSearchManager.java +++ b/legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/TranscriptSearchManager.java @@ -20,8 +20,9 @@ package org.jivesoftware.smackx.workgroup.agent; import org.jivesoftware.smackx.search.ReportedData; import org.jivesoftware.smackx.workgroup.packet.TranscriptSearch; import org.jivesoftware.smackx.xdata.Form; +import org.jivesoftware.smack.SmackException.NoResponseException; import org.jivesoftware.smack.XMPPConnection; -import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.packet.IQ; /** @@ -45,9 +46,10 @@ public class TranscriptSearchManager { * * @param serviceJID the address of the workgroup service. * @return the Form to use for searching transcripts. - * @throws XMPPException if an error occurs while sending the request to the server. + * @throws XMPPErrorException + * @throws NoResponseException */ - public Form getSearchForm(String serviceJID) throws XMPPException { + public Form getSearchForm(String serviceJID) throws NoResponseException, XMPPErrorException { TranscriptSearch search = new TranscriptSearch(); search.setType(IQ.Type.GET); search.setTo(serviceJID); @@ -65,9 +67,10 @@ public class TranscriptSearchManager { * @param serviceJID the address of the workgroup service. * @param completedForm the filled out search form. * @return the result of the transcript search. - * @throws XMPPException if an error occurs while submiting the search to the server. + * @throws XMPPErrorException + * @throws NoResponseException */ - public ReportedData submitSearch(String serviceJID, Form completedForm) throws XMPPException { + public ReportedData submitSearch(String serviceJID, Form completedForm) throws NoResponseException, XMPPErrorException { TranscriptSearch search = new TranscriptSearch(); search.setType(IQ.Type.GET); search.setTo(serviceJID); diff --git a/legacy/src/main/java/org/jivesoftware/smackx/workgroup/user/Workgroup.java b/legacy/src/main/java/org/jivesoftware/smackx/workgroup/user/Workgroup.java index 869383865..8c2780e85 100644 --- a/legacy/src/main/java/org/jivesoftware/smackx/workgroup/user/Workgroup.java +++ b/legacy/src/main/java/org/jivesoftware/smackx/workgroup/user/Workgroup.java @@ -29,6 +29,8 @@ import org.jivesoftware.smackx.xdata.Form; import org.jivesoftware.smackx.xdata.FormField; import org.jivesoftware.smackx.xdata.packet.DataForm; import org.jivesoftware.smack.*; +import org.jivesoftware.smack.SmackException.NoResponseException; +import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.filter.*; import org.jivesoftware.smack.packet.*; import org.jivesoftware.smack.util.StringUtils; @@ -153,9 +155,10 @@ public class Workgroup { * available only when agents are available for this workgroup. * * @return true if the workgroup is available for receiving new requests. - * @throws XMPPException + * @throws XMPPErrorException + * @throws NoResponseException */ - public boolean isAvailable() throws XMPPException { + public boolean isAvailable() throws NoResponseException, XMPPErrorException { Presence directedPresence = new Presence(Presence.Type.available); directedPresence.setTo(workgroupJID); PacketFilter typeFilter = new PacketTypeFilter(Presence.class); @@ -230,8 +233,9 @@ public class Workgroup { * @throws XMPPException if an error occured joining the queue. An error may indicate * that a connection failure occured or that the server explicitly rejected the * request to join the queue. + * @throws SmackException */ - public void joinQueue() throws XMPPException { + public void joinQueue() throws XMPPException, SmackException { joinQueue(null); } @@ -267,8 +271,9 @@ public class Workgroup { * @throws XMPPException if an error occured joining the queue. An error may indicate * that a connection failure occured or that the server explicitly rejected the * request to join the queue. + * @throws SmackException */ - public void joinQueue(Form answerForm) throws XMPPException { + public void joinQueue(Form answerForm) throws XMPPException, SmackException { joinQueue(answerForm, null); } @@ -301,11 +306,12 @@ public class Workgroup { * @param answerForm the completed form associated with the join reqest. * @param userID String that represents the ID of the user when using anonymous sessions * or null if a userID should not be used. - * @throws XMPPException if an error occured joining the queue. An error may indicate + * @throws XMPPErrorException if an error occured joining the queue. An error may indicate * that a connection failure occured or that the server explicitly rejected the * request to join the queue. + * @throws NoResponseException */ - public void joinQueue(Form answerForm, String userID) throws XMPPException { + public void joinQueue(Form answerForm, String userID) throws NoResponseException, XMPPErrorException { // If already in the queue ignore the join request. if (inQueue) { throw new IllegalStateException("Already in queue " + workgroupJID); @@ -350,8 +356,9 @@ public class Workgroup { * @throws XMPPException if an error occured joining the queue. An error may indicate * that a connection failure occured or that the server explicitly rejected the * request to join the queue. + * @throws SmackException */ - public void joinQueue(Map metadata, String userID) throws XMPPException { + public void joinQueue(Map metadata, String userID) throws XMPPException, SmackException { // If already in the queue ignore the join request. if (inQueue) { throw new IllegalStateException("Already in queue " + workgroupJID); @@ -383,10 +390,11 @@ public class Workgroup { * under certain circumstances -- for example, if they no longer wish to be routed * to an agent because they've been waiting too long. * - * @throws XMPPException if an error occured trying to send the depart queue + * @throws XMPPErrorException if an error occured trying to send the depart queue * request to the server. + * @throws NoResponseException */ - public void departQueue() throws XMPPException { + public void departQueue() throws NoResponseException, XMPPErrorException { // If not in the queue ignore the depart request. if (!inQueue) { return; @@ -589,8 +597,9 @@ public class Workgroup { * @param key the key to find. * @return the ChatSetting if found, otherwise false. * @throws XMPPException if an error occurs while getting information from the server. + * @throws SmackException */ - public ChatSetting getChatSetting(String key) throws XMPPException { + public ChatSetting getChatSetting(String key) throws XMPPException, SmackException { ChatSettings chatSettings = getChatSettings(key, -1); return chatSettings.getFirstEntry(); } @@ -601,8 +610,9 @@ public class Workgroup { * @param type the type of ChatSettings to return. * @return the ChatSettings of given type, otherwise null. * @throws XMPPException if an error occurs while getting information from the server. + * @throws SmackException */ - public ChatSettings getChatSettings(int type) throws XMPPException { + public ChatSettings getChatSettings(int type) throws XMPPException, SmackException { return getChatSettings(null, type); } @@ -611,8 +621,9 @@ public class Workgroup { * * @return all ChatSettings of a given workgroup. * @throws XMPPException if an error occurs while getting information from the server. + * @throws SmackException */ - public ChatSettings getChatSettings() throws XMPPException { + public ChatSettings getChatSettings() throws XMPPException, SmackException { return getChatSettings(null, -1); } @@ -621,9 +632,10 @@ public class Workgroup { * Asks the workgroup for it's Chat Settings. * * @return key specify a key to retrieve only that settings. Otherwise for all settings, key should be null. - * @throws XMPPException if an error occurs while getting information from the server. + * @throws NoResponseException + * @throws XMPPErrorException if an error occurs while getting information from the server. */ - private ChatSettings getChatSettings(String key, int type) throws XMPPException { + private ChatSettings getChatSettings(String key, int type) throws NoResponseException, XMPPErrorException { ChatSettings request = new ChatSettings(); if (key != null) { request.setKey(key); @@ -644,8 +656,9 @@ public class Workgroup { * to see if the email service has been configured and is available. * * @return true if the email service is available, otherwise return false. + * @throws SmackException */ - public boolean isEmailAvailable() { + public boolean isEmailAvailable() throws SmackException { ServiceDiscoveryManager discoManager = ServiceDiscoveryManager.getInstanceFor(connection); try { @@ -662,9 +675,10 @@ public class Workgroup { * Asks the workgroup for it's Offline Settings. * * @return offlineSettings the offline settings for this workgroup. - * @throws XMPPException if an error occurs while getting information from the server. + * @throws XMPPErrorException + * @throws NoResponseException */ - public OfflineSettings getOfflineSettings() throws XMPPException { + public OfflineSettings getOfflineSettings() throws NoResponseException, XMPPErrorException { OfflineSettings request = new OfflineSettings(); request.setType(IQ.Type.GET); request.setTo(workgroupJID); @@ -678,9 +692,10 @@ public class Workgroup { * Asks the workgroup for it's Sound Settings. * * @return soundSettings the sound settings for the specified workgroup. - * @throws XMPPException if an error occurs while getting information from the server. + * @throws XMPPErrorException + * @throws NoResponseException */ - public SoundSettings getSoundSettings() throws XMPPException { + public SoundSettings getSoundSettings() throws NoResponseException, XMPPErrorException { SoundSettings request = new SoundSettings(); request.setType(IQ.Type.GET); request.setTo(workgroupJID); @@ -693,9 +708,10 @@ public class Workgroup { * Asks the workgroup for it's Properties * * @return the WorkgroupProperties for the specified workgroup. - * @throws XMPPException if an error occurs while getting information from the server. + * @throws XMPPErrorException + * @throws NoResponseException */ - public WorkgroupProperties getWorkgroupProperties() throws XMPPException { + public WorkgroupProperties getWorkgroupProperties() throws NoResponseException, XMPPErrorException { WorkgroupProperties request = new WorkgroupProperties(); request.setType(IQ.Type.GET); request.setTo(workgroupJID); @@ -710,9 +726,10 @@ public class Workgroup { * * @param jid the jid of the user who's information you would like the workgroup to retreive. * @return the WorkgroupProperties for the specified workgroup. - * @throws XMPPException if an error occurs while getting information from the server. + * @throws XMPPErrorException + * @throws NoResponseException */ - public WorkgroupProperties getWorkgroupProperties(String jid) throws XMPPException { + public WorkgroupProperties getWorkgroupProperties(String jid) throws NoResponseException, XMPPErrorException { WorkgroupProperties request = new WorkgroupProperties(); request.setJid(jid); request.setType(IQ.Type.GET); @@ -730,9 +747,10 @@ public class Workgroup { * for future submissions. * * @return the Form to use for searching transcripts. - * @throws XMPPException if an error occurs while sending the request to the server. + * @throws XMPPErrorException + * @throws NoResponseException */ - public Form getWorkgroupForm() throws XMPPException { + public Form getWorkgroupForm() throws NoResponseException, XMPPErrorException { WorkgroupForm workgroupForm = new WorkgroupForm(); workgroupForm.setType(IQ.Type.GET); workgroupForm.setTo(workgroupJID); diff --git a/tcp/src/main/java/org/jivesoftware/smack/PacketReader.java b/tcp/src/main/java/org/jivesoftware/smack/PacketReader.java index 76159ee06..bf5c392e7 100644 --- a/tcp/src/main/java/org/jivesoftware/smack/PacketReader.java +++ b/tcp/src/main/java/org/jivesoftware/smack/PacketReader.java @@ -20,13 +20,16 @@ package org.jivesoftware.smack; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.Packet; import org.jivesoftware.smack.packet.Presence; -import org.jivesoftware.smack.packet.XMPPError; import org.jivesoftware.smack.parsing.ParsingExceptionCallback; import org.jivesoftware.smack.parsing.UnparsablePacket; import org.jivesoftware.smack.sasl.SASLMechanism.Challenge; -import org.jivesoftware.smack.sasl.SASLMechanism.Failure; +import org.jivesoftware.smack.sasl.SASLMechanism.SASLFailure; import org.jivesoftware.smack.sasl.SASLMechanism.Success; import org.jivesoftware.smack.util.PacketParserUtils; + +import org.jivesoftware.smack.SmackException.NoResponseException; +import org.jivesoftware.smack.SmackException.SecurityRequiredException; +import org.jivesoftware.smack.XMPPException.StreamErrorException; import org.xmlpull.v1.XmlPullParserFactory; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; @@ -82,11 +85,10 @@ class PacketReader { * Starts the packet reader thread and returns once a connection to the server * has been established. A connection will be attempted for a maximum of five * seconds. An XMPPException will be thrown if the connection fails. - * - * @throws XMPPException if the server fails to send an opening stream back - * for more than five seconds. + * @throws NoResponseException if the server fails to send an opening stream back + * within packetReplyTimeout*3. */ - synchronized public void startup() throws XMPPException { + synchronized public void startup() throws NoResponseException { readerThread.start(); // Wait for stream tag before returning. We'll wait a couple of seconds before // giving up and throwing an error. @@ -95,14 +97,14 @@ class PacketReader { // (although this is a rare thing). Therefore, we continue waiting // until either a connectionID has been set (and hence a notify was // made) or the total wait time has elapsed. - int waitTime = SmackConfiguration.getDefaultPacketReplyTimeout(); + long waitTime = connection.getPacketReplyTimeout(); wait(3 * waitTime); } catch (InterruptedException ie) { // Ignore. } if (connectionID == null) { - throw new XMPPException("XMPPConnection failed. No response from server."); + throw new NoResponseException(); } else { connection.connectionID = connectionID; @@ -225,7 +227,7 @@ class PacketReader { } } else if (parser.getName().equals("error")) { - throw new XMPPException(PacketParserUtils.parseStreamError(parser)); + throw new StreamErrorException(PacketParserUtils.parseStreamError(parser)); } else if (parser.getName().equals("features")) { parseFeatures(parser); @@ -252,9 +254,9 @@ class PacketReader { else { // SASL authentication has failed. The server may close the connection // depending on the number of retries - final Failure failure = PacketParserUtils.parseSASLFailure(parser); + final SASLFailure failure = PacketParserUtils.parseSASLFailure(parser); connection.processPacket(failure); - connection.getSASLAuthentication().authenticationFailed(failure.getCondition()); + connection.getSASLAuthentication().authenticationFailed(failure); } } else if (parser.getName().equals("challenge")) { @@ -390,9 +392,7 @@ class PacketReader { if (!startTLSReceived && connection.getConfiguration().getSecurityMode() == ConnectionConfiguration.SecurityMode.required) { - throw new XMPPException("Server does not support security (TLS), " + - "but security required by connection configuration.", - new XMPPError(XMPPError.Condition.forbidden)); + throw new SecurityRequiredException(); } } diff --git a/tcp/src/main/java/org/jivesoftware/smack/TCPConnection.java b/tcp/src/main/java/org/jivesoftware/smack/TCPConnection.java index 34434212f..b17e26bce 100644 --- a/tcp/src/main/java/org/jivesoftware/smack/TCPConnection.java +++ b/tcp/src/main/java/org/jivesoftware/smack/TCPConnection.java @@ -16,10 +16,12 @@ */ package org.jivesoftware.smack; +import org.jivesoftware.smack.SmackException.AlreadyLoggedInException; +import org.jivesoftware.smack.SmackException.NotConnectedException; +import org.jivesoftware.smack.SmackException.ConnectionException; import org.jivesoftware.smack.compression.XMPPInputOutputStream; import org.jivesoftware.smack.packet.Packet; import org.jivesoftware.smack.packet.Presence; -import org.jivesoftware.smack.packet.XMPPError; import org.jivesoftware.smack.parsing.ParsingExceptionCallback; import org.jivesoftware.smack.util.StringUtils; import org.jivesoftware.smack.util.dns.HostAddress; @@ -31,6 +33,7 @@ import javax.net.ssl.SSLSocket; import javax.security.auth.callback.Callback; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.callback.PasswordCallback; +import javax.security.sasl.SaslException; import java.io.BufferedReader; import java.io.BufferedWriter; @@ -41,9 +44,9 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; +import java.io.UnsupportedEncodingException; import java.lang.reflect.Constructor; import java.net.Socket; -import java.net.UnknownHostException; import java.security.KeyStore; import java.security.Provider; import java.security.Security; @@ -218,12 +221,12 @@ public class TCPConnection extends XMPPConnection { } @Override - public synchronized void login(String username, String password, String resource) throws XMPPException { + public synchronized void login(String username, String password, String resource) throws XMPPException, SmackException, SaslException, IOException { if (!isConnected()) { - throw new IllegalStateException("Not connected to server."); + throw new NotConnectedException(); } if (authenticated) { - throw new IllegalStateException("Already logged in to server."); + throw new AlreadyLoggedInException(); } // Do partial version of nameprep on the username. username = username.toLowerCase().trim(); @@ -238,7 +241,7 @@ public class TCPConnection extends XMPPConnection { response = saslAuthentication.authenticate(resource, config.getCallbackHandler()); } } else { - throw new XMPPException("No non-anonymous SASL authentication mechanism available"); + throw new SaslException("No non-anonymous SASL authentication mechanism available"); } // Set the user. @@ -289,12 +292,12 @@ public class TCPConnection extends XMPPConnection { } @Override - public synchronized void loginAnonymously() throws XMPPException { + public synchronized void loginAnonymously() throws XMPPException, SmackException, SaslException, IOException { if (!isConnected()) { - throw new IllegalStateException("Not connected to server."); + throw new NotConnectedException(); } if (authenticated) { - throw new IllegalStateException("Already logged in to server."); + throw new AlreadyLoggedInException(); } String response; @@ -302,7 +305,7 @@ public class TCPConnection extends XMPPConnection { response = saslAuthentication.authenticateAnonymously(); } else { - throw new XMPPException("No anonymous SASL authentication mechanism available"); + throw new SaslException("No anonymous SASL authentication mechanism available"); } // Set the user value. @@ -331,7 +334,7 @@ public class TCPConnection extends XMPPConnection { } } - public Roster getRoster() { + public Roster getRoster() throws XMPPException, SmackException { // synchronize against login() synchronized(this) { // if connection is authenticated the roster is already set by login() @@ -475,11 +478,10 @@ public class TCPConnection extends XMPPConnection { packetWriter.sendPacket(packet); } - private void connectUsingConfiguration(ConnectionConfiguration config) throws XMPPException { - XMPPException exception = null; + private void connectUsingConfiguration(ConnectionConfiguration config) throws SmackException, IOException { + Exception exception = null; Iterator it = config.getHostAddresses().iterator(); List failedAddresses = new LinkedList(); - boolean xmppIOError = false; while (it.hasNext()) { exception = null; HostAddress hostAddress = it.next(); @@ -492,15 +494,8 @@ public class TCPConnection extends XMPPConnection { else { this.socket = config.getSocketFactory().createSocket(host, port); } - } catch (UnknownHostException uhe) { - String errorMessage = "Could not connect to " + host + ":" + port + "."; - exception = new XMPPException(errorMessage, new XMPPError(XMPPError.Condition.remote_server_timeout, - errorMessage), uhe); - } catch (IOException ioe) { - String errorMessage = "XMPPError connecting to " + host + ":" + port + "."; - exception = new XMPPException(errorMessage, new XMPPError(XMPPError.Condition.remote_server_error, - errorMessage), ioe); - xmppIOError = true; + } catch (Exception e) { + exception = e; } if (exception == null) { // We found a host to connect to, break here @@ -513,19 +508,7 @@ public class TCPConnection extends XMPPConnection { // There are no more host addresses to try // throw an exception and report all tried // HostAddresses in the exception - StringBuilder sb = new StringBuilder(); - for (HostAddress fha : failedAddresses) { - sb.append(fha.getErrorMessage()); - sb.append("; "); - } - XMPPError xmppError; - if (xmppIOError) { - xmppError = new XMPPError(XMPPError.Condition.remote_server_error); - } - else { - xmppError = new XMPPError(XMPPError.Condition.remote_server_timeout); - } - throw new XMPPException(sb.toString(), xmppError, exception); + throw new ConnectionException(failedAddresses); } } socketClosed = false; @@ -537,8 +520,10 @@ public class TCPConnection extends XMPPConnection { * XMPP stream to the server. * * @throws XMPPException if establishing a connection to the server fails. + * @throws SmackException if the server failes to respond back or if there is anther error. + * @throws IOException */ - private void initConnection() throws XMPPException { + private void initConnection() throws SmackException, IOException { boolean isFirstInitialization = packetReader == null || packetWriter == null; compressionHandler = null; serverAckdCompression = false; @@ -582,7 +567,7 @@ public class TCPConnection extends XMPPConnection { } } - catch (XMPPException ex) { + catch (Exception ex) { // An exception occurred in setting up the connection. Make sure we shut down the // readers and writers and close the socket. @@ -625,11 +610,11 @@ public class TCPConnection extends XMPPConnection { authenticated = false; connected = false; - throw ex; // Everything stoppped. Now throw the exception. + throw new SmackException(ex); // Everything stoppped. Now throw the exception. } } - private void initReaderAndWriter() throws XMPPException { + private void initReaderAndWriter() throws IOException { try { if (compressionHandler == null) { reader = @@ -655,12 +640,8 @@ public class TCPConnection extends XMPPConnection { } } } - catch (IOException ioe) { - throw new XMPPException( - "XMPPError establishing connection with server.", - new XMPPError(XMPPError.Condition.remote_server_error, - "XMPPError establishing connection with server."), - ioe); + catch (UnsupportedEncodingException ioe) { + throw new IllegalStateException(ioe); } // If debugging is enabled, we open a window and write out all network traffic. @@ -932,12 +913,10 @@ public class TCPConnection extends XMPPConnection { * occurs after an abrupt termination. * * @throws XMPPException if an error occurs while trying to establish the connection. - * Two possible errors can occur which will be wrapped by an XMPPException -- - * UnknownHostException (XMPP error code 504), and IOException (XMPP error code - * 502). The error codes and wrapped exceptions can be used to present more - * appropriate error messages to end-users. + * @throws SmackException + * @throws IOException */ - public void connect() throws XMPPException { + public void connect() throws SmackException, IOException, XMPPException { // Establishes the connection, readers and writers connectUsingConfiguration(config); // Automatically makes the login if the user was previously connected successfully diff --git a/tcp/src/test/java/org/jivesoftware/smack/RosterOfflineTest.java b/tcp/src/test/java/org/jivesoftware/smack/RosterOfflineTest.java index ccbddfa77..5f549b20d 100644 --- a/tcp/src/test/java/org/jivesoftware/smack/RosterOfflineTest.java +++ b/tcp/src/test/java/org/jivesoftware/smack/RosterOfflineTest.java @@ -18,11 +18,6 @@ package org.jivesoftware.smack; import static org.junit.Assert.*; -import java.util.Collection; -import java.util.Iterator; - -import org.jivesoftware.smack.Roster.SubscriptionMode; -import org.jivesoftware.smack.packet.Presence; import org.junit.Before; import org.junit.Test; @@ -38,7 +33,7 @@ public class RosterOfflineTest { Roster roster; @Before - public void setup() { + public void setup() throws XMPPException, SmackException { this.connection = new TCPConnection("localhost"); assertFalse(connection.isConnected()); @@ -46,61 +41,22 @@ public class RosterOfflineTest { assertNotNull(roster); } - @Test - public void shouldThrowNoExceptionOnGetterMethods() { - // all getter methods should work - assertFalse(roster.contains("test")); - - Collection entries = roster.getEntries(); - assertTrue(entries.size() == 0); - - assertNull(roster.getEntry("test")); - - assertEquals(0, roster.getEntryCount()); - - assertNull(roster.getGroup("test")); - - assertEquals(0, roster.getGroupCount()); - - Collection groups = roster.getGroups(); - assertEquals(0, groups.size()); - - Presence presence = roster.getPresence("test"); - assertEquals(Presence.Type.unavailable, presence.getType()); - - Presence presenceResource = roster.getPresenceResource("test"); - assertEquals(Presence.Type.unavailable, presenceResource.getType()); - - Iterator iterator = roster.getPresences("test"); - assertTrue(iterator.hasNext()); - assertEquals(Presence.Type.unavailable, iterator.next().getType()); - assertFalse(iterator.hasNext()); - - assertEquals(0, roster.getUnfiledEntries().size()); - - assertEquals(0, roster.getUnfiledEntryCount()); - - roster.setSubscriptionMode(SubscriptionMode.accept_all); - assertEquals(SubscriptionMode.accept_all, roster.getSubscriptionMode()); - - } - - @Test(expected = IllegalStateException.class) + @Test(expected = SmackException.class) public void shouldThrowExceptionOnCreateEntry() throws Exception { roster.createEntry("test", "test", null); } - @Test(expected = IllegalStateException.class) + @Test(expected = SmackException.class) public void shouldThrowExceptionOnCreateGroup() throws Exception { roster.createGroup("test"); } - @Test(expected = IllegalStateException.class) + @Test(expected = SmackException.class) public void shouldThrowExceptionOnReload() throws Exception { roster.reload(); } - @Test(expected = IllegalStateException.class) + @Test(expected = SmackException.class) public void shouldThrowExceptionRemoveEntry() throws Exception { roster.removeEntry(null); }