1
0
Fork 0
mirror of https://github.com/vanitasvitae/Smack.git synced 2024-06-26 13:24:49 +02:00
Smack/smack-core/src/main/java/org/jivesoftware/smack/packet/StreamError.java
Florian Schmaus 3d4e7938a7 Make ExtensionElement marker interface wrt. QNAME field
ExtensionElement is now a marker interface that requires all
implementation non-abstract classes to carry a static final QNAME
field (of type QName). This is verified by a new unit test.

Also FullyQualifiedElement is renamed to simply XmlElement. XmlElement
is used over ExtensionElement when implementing classes do not
statically know the qualified name of the XML elements they
represent. In general, XmlElement should be used sparingly, and every
XML element should be modeled by its own Java class (implementing
ExtensionElement).
2021-04-18 21:07:19 +02:00

216 lines
8.6 KiB
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> Rthe server is unable to properly connect
* to a remote entity. </td></tr>
* <tr><td> resource-constraint </td><td> Rthe 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;
}
}