StreamError.java
- /**
- *
- * Copyright 2003-2005 Jive Software.
- *
- * 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.packet;
- import java.util.List;
- import java.util.Map;
- import org.jivesoftware.smack.util.StringUtils;
- import org.jivesoftware.smack.util.XmlStringBuilder;
- /**
- * Represents a stream error packet. Stream errors are unrecoverable errors where the server
- * will close the underlying TCP connection after the stream error was sent to the client.
- * These is the list of stream errors as defined in the XMPP spec:
- *
- * <table border=1>
- * <caption>Stream Errors</caption>
- * <tr><td><b>Code</b></td><td><b>Description</b></td></tr>
- * <tr><td> bad-format </td><td> the entity has sent XML that cannot be processed </td></tr>
- * <tr><td> unsupported-encoding </td><td> the entity has sent a namespace prefix that is
- * unsupported </td></tr>
- * <tr><td> bad-namespace-prefix </td><td> Remote Server Timeout </td></tr>
- * <tr><td> conflict </td><td> the server is closing the active stream for this entity
- * because a new stream has been initiated that conflicts with the existing
- * stream. </td></tr>
- * <tr><td> connection-timeout </td><td> the entity has not generated any traffic over
- * the stream for some period of time. </td></tr>
- * <tr><td> host-gone </td><td> the value of the 'to' attribute provided by the initiating
- * entity in the stream header corresponds to a hostname that is no longer hosted by
- * the server. </td></tr>
- * <tr><td> host-unknown </td><td> the value of the 'to' attribute provided by the
- * initiating entity in the stream header does not correspond to a hostname that is
- * hosted by the server. </td></tr>
- * <tr><td> improper-addressing </td><td> a stanza sent between two servers lacks a 'to'
- * or 'from' attribute </td></tr>
- * <tr><td> internal-server-error </td><td> the server has experienced a
- * misconfiguration. </td></tr>
- * <tr><td> invalid-from </td><td> the JID or hostname provided in a 'from' address does
- * not match an authorized JID. </td></tr>
- * <tr><td> invalid-namespace </td><td> the streams namespace name is invalid. </td></tr>
- * <tr><td> invalid-xml </td><td> the entity has sent invalid XML over the stream. </td></tr>
- * <tr><td> not-authorized </td><td> the entity has attempted to send data before the
- * stream has been authenticated </td></tr>
- * <tr><td> policy-violation </td><td> the entity has violated some local service
- * policy. </td></tr>
- * <tr><td> remote-connection-failed </td><td> the server is unable to properly connect
- * to a remote entity. </td></tr>
- * <tr><td> resource-constraint </td><td> the server lacks the system resources necessary
- * to service the stream. </td></tr>
- * <tr><td> restricted-xml </td><td> the entity has attempted to send restricted XML
- * features. </td></tr>
- * <tr><td> see-other-host </td><td> the server will not provide service to the initiating
- * entity but is redirecting traffic to another host. </td></tr>
- * <tr><td> system-shutdown </td><td> the server is being shut down and all active streams
- * are being closed. </td></tr>
- * <tr><td> undefined-condition </td><td> the error condition is not one of those defined
- * by the other conditions in this list. </td></tr>
- * <tr><td> unsupported-encoding </td><td> the initiating entity has encoded the stream in
- * an encoding that is not supported. </td></tr>
- * <tr><td> unsupported-stanza-type </td><td> the initiating entity has sent a first-level
- * child of the stream that is not supported. </td></tr>
- * <tr><td> unsupported-version </td><td> the value of the 'version' attribute provided by
- * the initiating entity in the stream header specifies a version of XMPP that is not
- * supported. </td></tr>
- * <tr><td> not-well-formed </td><td> the initiating entity has sent XML that is not
- * well-formed. </td></tr>
- * </table>
- * <p>
- * Stream error syntax:
- * <pre>
- * {@code
- * <stream:error>
- * <defined-condition xmlns='urn:ietf:params:xml:ns:xmpp-streams'/>
- * [<text xmlns='urn:ietf:params:xml:ns:xmpp-streams'
- * xml:lang='langcode'>
- * OPTIONAL descriptive text
- * </text>]
- * [OPTIONAL application-specific condition element]
- * </stream:error>
- * }
- * </pre>
- *
- * @author Gaston Dombiak
- */
- public class StreamError extends AbstractError implements Nonza {
- public static final String ELEMENT = "stream:error";
- public static final String NAMESPACE = "urn:ietf:params:xml:ns:xmpp-streams";
- private final Condition condition;
- private final String conditionText;
- public StreamError(Condition condition, String conditionText, Map<String, String> descriptiveTexts, List<XmlElement> extensions) {
- super(descriptiveTexts, extensions);
- // Some implementations may send the condition as non-empty element containing the empty string, that is
- // <condition xmlns='foo'></condition>, in this case the parser may calls this constructor with the empty string
- // as conditionText, therefore reset it to null if it's the empty string
- if (StringUtils.isNullOrEmpty(conditionText)) {
- conditionText = null;
- }
- if (conditionText != null) {
- switch (condition) {
- case see_other_host:
- break;
- default:
- throw new IllegalArgumentException("The given condition '" + condition
- + "' can not contain a conditionText");
- }
- }
- this.condition = condition;
- this.conditionText = conditionText;
- }
- public Condition getCondition() {
- return condition;
- }
- public String getConditionText() {
- return conditionText;
- }
- @Override
- public String toString() {
- return toXML().toString();
- }
- @Override
- public XmlStringBuilder toXML(org.jivesoftware.smack.packet.XmlEnvironment enclosingNamespace) {
- XmlStringBuilder xml = new XmlStringBuilder();
- xml.openElement(ELEMENT);
- xml.halfOpenElement(condition.toString()).xmlnsAttribute(NAMESPACE).closeEmptyElement();
- addDescriptiveTextsAndExtensions(xml);
- xml.closeElement(ELEMENT);
- return xml;
- }
- /**
- * The defined stream error conditions, see RFC 6120 ยง 4.9.3.
- *
- */
- public enum Condition {
- bad_format,
- bad_namespace_prefix,
- conflict,
- connection_timeout,
- host_gone,
- host_unknown,
- improper_addressing,
- internal_server_error,
- invalid_from,
- invalid_namespace,
- invalid_xml,
- not_authorized,
- not_well_formed,
- policy_violation,
- remote_connection_failed,
- reset,
- resource_constraint,
- restricted_xml,
- see_other_host,
- system_shutdown,
- undefined_condition,
- unsupported_encoding,
- unsupported_feature,
- unsupported_stanza_type,
- unsupported_version;
- @Override
- public String toString() {
- return this.name().replace('_', '-');
- }
- public static Condition fromString(String string) {
- // Backwards compatibility for older implementations still using RFC 3920. RFC 6120
- // changed 'xml-not-well-formed' to 'not-well-formed'.
- if ("xml-not-well-formed".equals(string)) {
- string = "not-well-formed";
- }
- string = string.replace('-', '_');
- Condition condition = null;
- try {
- condition = Condition.valueOf(string);
- } catch (Exception e) {
- throw new IllegalStateException("Could not transform string '" + string
- + "' to XMPPErrorCondition", e);
- }
- return condition;
- }
- }
- @Override
- public String getNamespace() {
- return NAMESPACE;
- }
- @Override
- public String getElementName() {
- return ELEMENT;
- }
- }