📄 packeterror.java
字号:
/**
* $RCSfile$
* $Revision: 3513 $
* $Date: 2006-03-02 12:06:44 -0800 (Thu, 02 Mar 2006) $
*
* Copyright 2004 Jive Software.
*
* All rights reserved. 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.xmpp.packet;
import org.dom4j.DocumentFactory;
import org.dom4j.Element;
import org.dom4j.QName;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;
import java.io.StringWriter;
import java.util.Iterator;
/**
* A packet error. Errors must have a type and condition. Optionally, they
* can include explanation text.
*
* @author Matt Tucker
*/
public class PacketError {
private static final String ERROR_NAMESPACE = "urn:ietf:params:xml:ns:xmpp-stanzas";
private static DocumentFactory docFactory = DocumentFactory.getInstance();
private Element element;
/**
* Construcs a new PacketError with the specified condition. The error
* type will be set to the default for the specified condition.
*
* @param condition the error condition.
*/
public PacketError(Condition condition) {
this.element = docFactory.createElement("error");
setCondition(condition);
setType(condition.getDefaultType());
}
/**
* Constructs a new PacketError with the specified condition and type.
*
* @param condition the error condition.
* @param type the error type.
*/
public PacketError(Condition condition, Type type) {
this.element = docFactory.createElement("error");
setCondition(condition);
setType(type);
}
/**
* Constructs a new PacketError.
*
* @param type the error type.
* @param condition the error condition.
* @param text the text description of the error.
*/
public PacketError(Condition condition, Type type, String text) {
this.element = docFactory.createElement("error");
setType(type);
setCondition(condition);
setText(text, null);
}
/**
* Constructs a new PacketError.
*
* @param type the error type.
* @param condition the error condition.
* @param text the text description of the error.
* @param lang the language code of the error description (e.g. "en").
*/
public PacketError(Condition condition, Type type, String text, String lang) {
this.element = docFactory.createElement("error");
setType(type);
setCondition(condition);
setText(text, lang);
}
/**
* Constructs a new PacketError using an existing Element. This is useful
* for parsing incoming error Elements into PacketError objects.
*
* @param element the error Element.
*/
public PacketError(Element element) {
this.element = element;
}
/**
* Returns the error type.
*
* @return the error type.
* @see Type
*/
public Type getType() {
String type = element.attributeValue("type");
if (type != null) {
return Type.fromXMPP(type);
}
else {
return null;
}
}
/**
* Sets the error type.
*
* @param type the error type.
* @see Type
*/
public void setType(Type type) {
element.addAttribute("type", type==null?null:type.toXMPP());
}
/**
* Returns the error condition.
*
* @return the error condition.
* @see Condition
*/
public Condition getCondition() {
for (Iterator i=element.elementIterator(); i.hasNext(); ) {
Element el = (Element)i.next();
if (el.getNamespaceURI().equals(ERROR_NAMESPACE) &&
!el.getName().equals("text"))
{
return Condition.fromXMPP(el.getName());
}
}
// Looking for XMPP condition failed. See if a legacy error code exists,
// which can be mapped into an XMPP error condition.
String code = element.attributeValue("code");
if (code != null) {
try {
return Condition.fromLegacyCode(Integer.parseInt(code));
}
catch (Exception e) {
// Ignore -- unable to map legacy code into a valid condition
// so return null.
}
}
return null;
}
/**
* Sets the error condition.
*
* @param condition the error condition.
* @see Condition
*/
public void setCondition(Condition condition) {
if (condition == null) {
throw new NullPointerException("Condition cannot be null");
}
// Set the error code for legacy support.
element.addAttribute("code", Integer.toString(condition.getLegacyCode()));
Element conditionElement = null;
for (Iterator i=element.elementIterator(); i.hasNext(); ) {
Element el = (Element)i.next();
if (el.getNamespaceURI().equals(ERROR_NAMESPACE) &&
!el.getName().equals("text"))
{
conditionElement = el;
}
}
if (conditionElement != null) {
element.remove(conditionElement);
}
conditionElement = docFactory.createElement(condition.toXMPP(),
ERROR_NAMESPACE);
element.add(conditionElement);
}
/**
* Returns a text description of the error, or <tt>null</tt> if there
* is no text description.
*
* @return the text description of the error.
*/
public String getText() {
return element.elementText("text");
}
/**
* Sets the text description of the error.
*
* @param text the text description of the error.
*/
public void setText(String text) {
setText(text, null);
}
/**
* Sets the text description of the error. Optionally, a language code
* can be specified to indicate the language of the description.
*
* @param text the text description of the error.
* @param lang the language code of the description, or <tt>null</tt> to specify
* no language code.
*/
public void setText(String text, String lang) {
Element textElement = element.element("text");
// If text is null, clear the text.
if (text == null) {
if (textElement != null) {
element.remove(textElement);
}
return;
}
if (textElement == null) {
textElement = docFactory.createElement("text", ERROR_NAMESPACE);
if (lang != null) {
textElement.addAttribute(QName.get("lang", "xml",
"http://www.w3.org/XML/1998/namespace"), lang);
}
element.add(textElement);
}
textElement.setText(text);
}
/**
* Returns the text description's language code, or <tt>null</tt> if there
* is no language code associated with the description text.
*
* @return the language code of the text description, if it exists.
*/
public String getTextLang() {
Element textElement = element.element("text");
if (textElement != null) {
return textElement.attributeValue(QName.get("lang", "xml",
"http://www.w3.org/XML/1998/namespace"));
}
return null;
}
/**
* Returns the DOM4J Element that backs the error. The element is the definitive
* representation of the error and can be manipulated directly to change
* error contents.
*
* @return the DOM4J Element.
*/
public Element getElement() {
return element;
}
/**
* Returns the textual XML representation of this error.
*
* @return the textual XML representation of this error.
*/
public String toXML() {
return element.asXML();
}
public String toString() {
StringWriter out = new StringWriter();
XMLWriter writer = new XMLWriter(out, OutputFormat.createPrettyPrint());
try {
writer.write(element);
}
catch (Exception e) {
// Ignore.
}
return out.toString();
}
/**
* Type-safe enumeration for the error condition.<p>
*
* Implementation note: XMPP error conditions use "-" characters in
* their names such as "bad-request". Because "-" characters are not valid
* identifier parts in Java, they have been converted to "_" characters in
* the enumeration names, such as <tt>bad_request</tt>. The {@link #toXMPP()} and
* {@link #fromXMPP(String)} methods can be used to convert between the
* enumertation values and XMPP error code strings.
*/
public enum Condition {
/**
* The sender has sent XML that is malformed or that cannot be processed
* (e.g., an IQ stanza that includes an unrecognized value of the 'type'
* attribute); the associated error type SHOULD be "modify".
*/
bad_request("bad-request", Type.modify, 400),
/**
* Access cannot be granted because an existing resource or session
* exists with the same name or address; the associated error type
* SHOULD be "cancel".
*/
conflict("conflict", Type.cancel, 409),
/**
* The feature requested is not implemented by the recipient or
* server and therefore cannot be processed; the associated error
* type SHOULD be "cancel".
*/
feature_not_implemented("feature-not-implemented", Type.cancel, 501),
/**
* The requesting entity does not possess the required permissions to
* perform the action; the associated error type SHOULD be "auth".
*/
forbidden("forbidden", Type.auth, 403),
/**
* The recipient or server can no longer be contacted at this address
* (the error stanza MAY contain a new address in the XML character
* data of the <gone/> element); the associated error type SHOULD be
* "modify".
*/
gone("gone", Type.modify, 302),
/**
* The server could not process the stanza because of a misconfiguration
* or an otherwise-undefined internal server error; the associated error
* type SHOULD be "wait".
*/
internal_server_error("internal-server-error", Type.wait, 500),
/**
* The addressed JID or item requested cannot be found; the associated
* error type SHOULD be "cancel".
*/
item_not_found("item-not-found", Type.cancel, 404),
/**
* The sending entity has provided or communicated an XMPP address
* (e.g., a value of the 'to' attribute) or aspect thereof (e.g.,
* a resource identifier) that does not adhere to the syntax defined
* in Addressing Scheme (Section 3); the associated error type SHOULD
* be "modify".
*/
jid_malformed("jid-malformed", Type.modify, 400),
/**
* The recipient or server understands the request but is refusing
* to process it because it does not meet criteria defined by the
* recipient or server (e.g., a local policy regarding acceptable
* words in messages); the associated error type SHOULD be "modify".
*/
not_acceptable("not-acceptable", Type.modify, 406),
/**
* The recipient or server does not allow any entity to perform
* the action; the associated error type SHOULD be "cancel".
*/
not_allowed("not-allowed", Type.cancel, 405),
/**
* The sender must provide proper credentials before being allowed
* to perform the action, or has provided improper credentials;
* the associated error type SHOULD be "auth".
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -