001/** 002 * 003 * Copyright 2014 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 super("Client is not, or no longer, connected"); 156 } 157 } 158 159 public static class IllegalStateChangeException extends SmackException { 160 161 /** 162 * 163 */ 164 private static final long serialVersionUID = -1766023961577168927L; 165 166 public IllegalStateChangeException() { 167 } 168 } 169 170 public static abstract class SecurityRequiredException extends SmackException { 171 172 /** 173 * 174 */ 175 private static final long serialVersionUID = 384291845029773545L; 176 177 public SecurityRequiredException(String message) { 178 super(message); 179 } 180 } 181 182 public static class SecurityRequiredByClientException extends SecurityRequiredException { 183 /** 184 * 185 */ 186 private static final long serialVersionUID = 2395325821201543159L; 187 188 public SecurityRequiredByClientException() { 189 super("SSL/TLS required by client but not supported by server"); 190 } 191 } 192 193 public static class SecurityRequiredByServerException extends SecurityRequiredException { 194 /** 195 * 196 */ 197 private static final long serialVersionUID = 8268148813117631819L; 198 199 public SecurityRequiredByServerException() { 200 super("SSL/TLS required by server but disabled in client"); 201 } 202 } 203 204 public static class SecurityNotPossibleException extends SmackException { 205 206 /** 207 * 208 */ 209 private static final long serialVersionUID = -6836090872690331336L; 210 211 public SecurityNotPossibleException(String message) { 212 super(message); 213 } 214 } 215 216 /** 217 * ConnectionException is thrown if Smack is unable to connect to all hosts of a given XMPP 218 * service. The failed hosts can be retrieved with 219 * {@link ConnectionException#getFailedAddresses()}, which will have the exception causing the 220 * connection failure set and retrievable with {@link HostAddress#getException()}. 221 */ 222 public static class ConnectionException extends SmackException { 223 224 /** 225 * 226 */ 227 private static final long serialVersionUID = 1686944201672697996L; 228 229 private final List<HostAddress> failedAddresses; 230 231 public ConnectionException(Throwable wrappedThrowable) { 232 super(wrappedThrowable); 233 failedAddresses = new ArrayList<HostAddress>(0); 234 } 235 236 private ConnectionException(String message, List<HostAddress> failedAddresses) { 237 super(message); 238 this.failedAddresses = failedAddresses; 239 } 240 241 public static ConnectionException from(List<HostAddress> failedAddresses) { 242 final String DELIMITER = ", "; 243 StringBuilder sb = new StringBuilder("The following addresses failed: "); 244 for (HostAddress hostAddress : failedAddresses) { 245 sb.append(hostAddress.getErrorMessage()); 246 sb.append(DELIMITER); 247 } 248 // Remove the last delimiter 249 sb.setLength(sb.length() - DELIMITER.length()); 250 return new ConnectionException(sb.toString(), failedAddresses); 251 } 252 253 public List<HostAddress> getFailedAddresses() { 254 return failedAddresses; 255 } 256 } 257 258 public static class FeatureNotSupportedException extends SmackException { 259 260 /** 261 * 262 */ 263 private static final long serialVersionUID = 4713404802621452016L; 264 265 private final String feature; 266 private final String jid; 267 268 public FeatureNotSupportedException(String feature) { 269 this(feature, null); 270 } 271 272 public FeatureNotSupportedException(String feature, String jid) { 273 super(feature + " not supported" + (jid == null ? "" : " by '" + jid + "'")); 274 this.jid = jid; 275 this.feature = feature; 276 } 277 278 /** 279 * Get the feature which is not supported. 280 * 281 * @return the feature which is not supported 282 */ 283 public String getFeature() { 284 return feature; 285 } 286 287 /** 288 * Get JID which does not support the feature. The JID can be null in cases when there are 289 * multiple JIDs queried for this feature. 290 * 291 * @return the JID which does not support the feature, or null 292 */ 293 public String getJid() { 294 return jid; 295 } 296 } 297 298 public static class ResourceBindingNotOfferedException extends SmackException { 299 300 /** 301 * 302 */ 303 private static final long serialVersionUID = 2346934138253437571L; 304 305 public ResourceBindingNotOfferedException() { 306 super("Resource binding was not offered by server"); 307 } 308 } 309}