001/** 002 * 003 * Copyright 2014-2015 Florian Schmaus 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); 006 * you may not use this file except in compliance with the License. 007 * You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.jivesoftware.smack; 018 019import java.util.ArrayList; 020import java.util.List; 021 022import org.jivesoftware.smack.filter.StanzaFilter; 023import org.jivesoftware.smack.util.dns.HostAddress; 024 025/** 026 * Smack uses SmackExceptions for errors that are not defined by any XMPP specification. 027 * 028 * @author Florian Schmaus 029 */ 030public class SmackException extends Exception { 031 032 /** 033 * 034 */ 035 private static final long serialVersionUID = 1844674365368214457L; 036 037 /** 038 * Creates a new SmackException with the Throwable that was the root cause of the exception. 039 * 040 * @param wrappedThrowable the root cause of the exception. 041 */ 042 public SmackException(Throwable wrappedThrowable) { 043 super(wrappedThrowable); 044 } 045 046 public SmackException(String message) { 047 super(message); 048 } 049 050 public SmackException(String message, Throwable wrappedThrowable) { 051 super(message, wrappedThrowable); 052 } 053 054 protected SmackException() { 055 } 056 057 /** 058 * Exception thrown always when there was no response to an request within the stanza(/packet) reply timeout of the used 059 * connection instance. You can modify (e.g. increase) the stanza(/packet) reply timeout with 060 * {@link XMPPConnection#setPacketReplyTimeout(long)}. 061 */ 062 public static class NoResponseException extends SmackException { 063 /** 064 * 065 */ 066 private static final long serialVersionUID = -6523363748984543636L; 067 068 private final StanzaFilter filter; 069 070 private NoResponseException(String message, StanzaFilter filter) { 071 super(message); 072 this.filter = filter; 073 } 074 075 /** 076 * Get the filter that was used to collect the response. 077 * 078 * @return the used filter or <code>null</code>. 079 */ 080 public StanzaFilter getFilter() { 081 return filter; 082 } 083 084 public static NoResponseException newWith(XMPPConnection connection) { 085 return newWith(connection, (StanzaFilter) null); 086 } 087 088 public static NoResponseException newWith(XMPPConnection connection, 089 PacketCollector collector) { 090 return newWith(connection, collector.getStanzaFilter()); 091 } 092 093 public static NoResponseException newWith(XMPPConnection connection, StanzaFilter filter) { 094 final long replyTimeout = connection.getPacketReplyTimeout(); 095 final StringBuilder sb = new StringBuilder(256); 096 sb.append("No response received within reply timeout. Timeout was " 097 + replyTimeout + "ms (~" 098 + replyTimeout / 1000 + "s). Used filter: "); 099 if (filter != null) { 100 sb.append(filter.toString()); 101 } 102 else { 103 sb.append("No filter used or filter was 'null'"); 104 } 105 sb.append('.'); 106 return new NoResponseException(sb.toString(), filter); 107 } 108 109 } 110 111 public static class NotLoggedInException extends SmackException { 112 113 /** 114 * 115 */ 116 private static final long serialVersionUID = 3216216839100019278L; 117 118 public NotLoggedInException() { 119 super("Client is not logged in"); 120 } 121 } 122 123 public static class AlreadyLoggedInException extends SmackException { 124 125 /** 126 * 127 */ 128 private static final long serialVersionUID = 5011416918049935231L; 129 130 public AlreadyLoggedInException() { 131 super("Client is already logged in"); 132 } 133 } 134 135 public static class AlreadyConnectedException extends SmackException { 136 137 /** 138 * 139 */ 140 private static final long serialVersionUID = 5011416918049135231L; 141 142 public AlreadyConnectedException() { 143 super("Client is already connected"); 144 } 145 } 146 147 public static class NotConnectedException extends SmackException { 148 149 /** 150 * 151 */ 152 private static final long serialVersionUID = 9197980400776001173L; 153 154 public NotConnectedException() { 155 this(null); 156 } 157 158 public NotConnectedException(String optionalHint) { 159 super("Client is not, or no longer, connected." 160 + (optionalHint != null ? ' ' + optionalHint : "")); 161 } 162 } 163 164 public static class IllegalStateChangeException extends SmackException { 165 166 /** 167 * 168 */ 169 private static final long serialVersionUID = -1766023961577168927L; 170 171 public IllegalStateChangeException() { 172 } 173 } 174 175 public static abstract class SecurityRequiredException extends SmackException { 176 177 /** 178 * 179 */ 180 private static final long serialVersionUID = 384291845029773545L; 181 182 public SecurityRequiredException(String message) { 183 super(message); 184 } 185 } 186 187 public static class SecurityRequiredByClientException extends SecurityRequiredException { 188 /** 189 * 190 */ 191 private static final long serialVersionUID = 2395325821201543159L; 192 193 public SecurityRequiredByClientException() { 194 super("SSL/TLS required by client but not supported by server"); 195 } 196 } 197 198 public static class SecurityRequiredByServerException extends SecurityRequiredException { 199 /** 200 * 201 */ 202 private static final long serialVersionUID = 8268148813117631819L; 203 204 public SecurityRequiredByServerException() { 205 super("SSL/TLS required by server but disabled in client"); 206 } 207 } 208 209 public static class SecurityNotPossibleException extends SmackException { 210 211 /** 212 * 213 */ 214 private static final long serialVersionUID = -6836090872690331336L; 215 216 public SecurityNotPossibleException(String message) { 217 super(message); 218 } 219 } 220 221 /** 222 * ConnectionException is thrown if Smack is unable to connect to all hosts of a given XMPP 223 * service. The failed hosts can be retrieved with 224 * {@link ConnectionException#getFailedAddresses()}, which will have the exception causing the 225 * connection failure set and retrievable with {@link HostAddress#getException()}. 226 */ 227 public static class ConnectionException extends SmackException { 228 229 /** 230 * 231 */ 232 private static final long serialVersionUID = 1686944201672697996L; 233 234 private final List<HostAddress> failedAddresses; 235 236 public ConnectionException(Throwable wrappedThrowable) { 237 super(wrappedThrowable); 238 failedAddresses = new ArrayList<HostAddress>(0); 239 } 240 241 private ConnectionException(String message, List<HostAddress> failedAddresses) { 242 super(message); 243 this.failedAddresses = failedAddresses; 244 } 245 246 public static ConnectionException from(List<HostAddress> failedAddresses) { 247 final String DELIMITER = ", "; 248 StringBuilder sb = new StringBuilder("The following addresses failed: "); 249 for (HostAddress hostAddress : failedAddresses) { 250 sb.append(hostAddress.getErrorMessage()); 251 sb.append(DELIMITER); 252 } 253 // Remove the last delimiter 254 sb.setLength(sb.length() - DELIMITER.length()); 255 return new ConnectionException(sb.toString(), failedAddresses); 256 } 257 258 public List<HostAddress> getFailedAddresses() { 259 return failedAddresses; 260 } 261 } 262 263 public static class FeatureNotSupportedException extends SmackException { 264 265 /** 266 * 267 */ 268 private static final long serialVersionUID = 4713404802621452016L; 269 270 private final String feature; 271 private final String jid; 272 273 public FeatureNotSupportedException(String feature) { 274 this(feature, null); 275 } 276 277 public FeatureNotSupportedException(String feature, String jid) { 278 super(feature + " not supported" + (jid == null ? "" : " by '" + jid + "'")); 279 this.jid = jid; 280 this.feature = feature; 281 } 282 283 /** 284 * Get the feature which is not supported. 285 * 286 * @return the feature which is not supported 287 */ 288 public String getFeature() { 289 return feature; 290 } 291 292 /** 293 * Get JID which does not support the feature. The JID can be null in cases when there are 294 * multiple JIDs queried for this feature. 295 * 296 * @return the JID which does not support the feature, or null 297 */ 298 public String getJid() { 299 return jid; 300 } 301 } 302 303 public static class ResourceBindingNotOfferedException extends SmackException { 304 305 /** 306 * 307 */ 308 private static final long serialVersionUID = 2346934138253437571L; 309 310 public ResourceBindingNotOfferedException() { 311 super("Resource binding was not offered by server"); 312 } 313 } 314}