KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > xmpp > packet > StreamError


1 /**
2  * $RCSfile: StreamError.java,v $
3  * $Revision: 1.3 $
4  * $Date: 2005/04/03 21:09:41 $
5  *
6  * Copyright 2005 Jive Software.
7  *
8  * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */

20
21 package org.xmpp.packet;
22
23 import org.dom4j.*;
24 import org.dom4j.io.XMLWriter;
25 import org.dom4j.io.OutputFormat;
26
27 import java.util.Iterator JavaDoc;
28 import java.io.StringWriter JavaDoc;
29
30 /**
31  * A stream error. Stream errors have a condition and they
32  * can optionally include explanation text.
33  *
34  * @author Matt Tucker
35  */

36 public class StreamError {
37
38     private static final String JavaDoc ERROR_NAMESPACE = "urn:ietf:params:xml:ns:xmpp-streams";
39
40     private static DocumentFactory docFactory = DocumentFactory.getInstance();
41
42     private Element element;
43
44     /**
45      * Construcs a new StreamError with the specified condition.
46      *
47      * @param condition the error condition.
48      */

49     public StreamError(Condition condition) {
50         this.element = docFactory.createElement(docFactory.createQName("error", "stream",
51                 "http://etherx.jabber.org/streams"));
52         setCondition(condition);
53     }
54
55     /**
56      * Constructs a new StreamError with the specified condition and error text.
57      *
58      * @param condition the error condition.
59      * @param text the text description of the error.
60      */

61     public StreamError(Condition condition, String JavaDoc text) {
62         this.element = docFactory.createElement(docFactory.createQName("error", "stream",
63                 "http://etherx.jabber.org/streams"));
64         setCondition(condition);
65         setText(text, null);
66     }
67
68     /**
69      * Constructs a new StreamError with the specified condition and error text.
70      *
71      * @param condition the error condition.
72      * @param text the text description of the error.
73      * @param language the language code of the error description (e.g. "en").
74      */

75     public StreamError(Condition condition, String JavaDoc text, String JavaDoc language) {
76         this.element = docFactory.createElement(docFactory.createQName("error", "stream",
77                 "http://etherx.jabber.org/streams"));
78         setCondition(condition);
79         setText(text, language);
80     }
81
82     /**
83      * Constructs a new StreamError using an existing Element. This is useful
84      * for parsing incoming error Elements into StreamError objects.
85      *
86      * @param element the stream error Element.
87      */

88     public StreamError(Element element) {
89         this.element = element;
90     }
91
92     /**
93      * Returns the error condition.
94      *
95      * @return the error condition.
96      * @see Condition
97      */

98     public Condition getCondition() {
99         for (Iterator JavaDoc i=element.elementIterator(); i.hasNext(); ) {
100             Element el = (Element)i.next();
101             if (el.getNamespaceURI().equals(ERROR_NAMESPACE) &&
102                     !el.getName().equals("text"))
103             {
104                 return Condition.fromXMPP(el.getName());
105             }
106         }
107         return null;
108     }
109
110     /**
111      * Sets the error condition.
112      *
113      * @param condition the error condition.
114      * @see Condition
115      */

116     public void setCondition(Condition condition) {
117         if (condition == null) {
118             throw new NullPointerException JavaDoc("Condition cannot be null");
119         }
120         Element conditionElement = null;
121         for (Iterator JavaDoc i=element.elementIterator(); i.hasNext(); ) {
122             Element el = (Element)i.next();
123             if (el.getNamespaceURI().equals(ERROR_NAMESPACE) &&
124                     !el.getName().equals("text"))
125             {
126                 conditionElement = el;
127             }
128         }
129         if (conditionElement != null) {
130             element.remove(conditionElement);
131         }
132
133         conditionElement = docFactory.createElement(condition.toXMPP(), ERROR_NAMESPACE);
134         element.add(conditionElement);
135     }
136
137     /**
138      * Returns a text description of the error, or <tt>null</tt> if there
139      * is no text description.
140      *
141      * @return the text description of the error.
142      */

143     public String JavaDoc getText() {
144         return element.elementText("text");
145     }
146
147     /**
148      * Sets the text description of the error.
149      *
150      * @param text the text description of the error.
151      */

152     public void setText(String JavaDoc text) {
153         setText(text, null);
154     }
155
156     /**
157      * Sets the text description of the error. Optionally, a language code
158      * can be specified to indicate the language of the description.
159      *
160      * @param text the text description of the error.
161      * @param language the language code of the description, or <tt>null</tt> to specify
162      * no language code.
163      */

164     public void setText(String JavaDoc text, String JavaDoc language) {
165         Element textElement = element.element("text");
166         // If text is null, clear the text.
167
if (text == null) {
168             if (textElement != null) {
169                 element.remove(textElement);
170             }
171             return;
172         }
173
174         if (textElement == null) {
175             textElement = docFactory.createElement("text", ERROR_NAMESPACE);
176             if (language != null) {
177                 textElement.addAttribute(QName.get("lang", "xml",
178                         "http://www.w3.org/XML/1998/namespace"), language);
179             }
180             element.add(textElement);
181         }
182         textElement.setText(text);
183     }
184
185     /**
186      * Returns the text description's language code, or <tt>null</tt> if there
187      * is no language code associated with the description text.
188      *
189      * @return the language code of the text description, if it exists.
190      */

191     public String JavaDoc getTextLanguage() {
192         Element textElement = element.element("text");
193         if (textElement != null) {
194             return textElement.attributeValue(QName.get("lang", "xml",
195                         "http://www.w3.org/XML/1998/namespace"));
196         }
197         return null;
198     }
199
200     /**
201      * Returns the DOM4J Element that backs the error. The element is the definitive
202      * representation of the error and can be manipulated directly to change
203      * error contents.
204      *
205      * @return the DOM4J Element.
206      */

207     public Element getElement() {
208         return element;
209     }
210
211     /**
212      * Returns the textual XML representation of this stream error.
213      *
214      * @return the textual XML representation of this stream error.
215      */

216     public String JavaDoc toXML() {
217         return element.asXML();
218     }
219
220     public String JavaDoc toString() {
221         StringWriter JavaDoc out = new StringWriter JavaDoc();
222         XMLWriter writer = new XMLWriter(out, OutputFormat.createPrettyPrint());
223         try {
224             writer.write(element);
225         }
226         catch (Exception JavaDoc e) { }
227         return out.toString();
228     }
229
230     /**
231      * Type-safe enumeration for the error condition.<p>
232      *
233      * Implementation note: XMPP error conditions use "-" characters in
234      * their names such as "bad-request". Because "-" characters are not valid
235      * identifier parts in Java, they have been converted to "_" characters in
236      * the enumeration names, such as <tt>bad_request</tt>. The {@link #toXMPP()} and
237      * {@link #fromXMPP(String)} methods can be used to convert between the
238      * enumertation values and XMPP error code strings.
239      */

240     public enum Condition {
241
242         /**
243          * The entity has sent XML that cannot be processed; this error MAY be used
244          * instead of the more specific XML-related errors, such as &lt;bad-namespace-prefix/&gt;,
245          * &lt;invalid-xml/&gt;, &lt;restricted-xml/&gt;, &lt;unsupported-encoding/&gt;, and
246          * &lt;xml-not-well-formed/&gt;, although the more specific errors are preferred.
247          */

248         bad_format("bad-format"),
249
250         /**
251          * The entity has sent a namespace prefix that is unsupported, or has sent no
252          * namespace prefix on an element that requires such a prefix.
253          */

254         bad_namespace_prefix("bad-namespace-prefix"),
255
256         /**
257          * The server is closing the active stream for this entity because a new stream
258          * has been initiated that conflicts with the existing stream.
259          */

260         conflict("conflict"),
261
262         /**
263          * The entity has not generated any traffic over the stream for some period of
264          * time (configurable according to a local service policy).
265          */

266         connection_timeout("connection-timeout"),
267
268         /**
269          * The value of the 'to' attribute provided by the initiating entity in the
270          * stream header corresponds to a hostname that is no longer hosted by the server.
271          */

272         host_gone("host-gone"),
273
274         /**
275          * The value of the 'to' attribute provided by the initiating entity in the
276          * stream header does not correspond to a hostname that is hosted by the server.
277          */

278         host_unknown("host-unknown"),
279
280         /**
281          * A stanza sent between two servers lacks a 'to' or 'from' attribute
282          * (or the attribute has no value).
283          */

284         improper_addressing("improper-addressing"),
285
286         /**
287          * The server has experienced a misconfiguration or an otherwise-undefined
288          * internal error that prevents it from servicing the stream.
289          */

290         internal_server_error("internal-server-error"),
291
292         /**
293          * The JID or hostname provided in a 'from' address does not match an authorized
294          * JID or validated domain negotiated between servers via SASL or dialback, or
295          * between a client and a server via authentication and resource binding.
296          */

297         invalid_from("invalid-from"),
298
299         /**
300          * The stream ID or dialback ID is invalid or does not match an ID previously provided.
301          */

302         invalid_id("invalid-id"),
303
304         /**
305          * the streams namespace name is something other than "http://etherx.jabber.org/streams"
306          * or the dialback namespace name is something other than "jabber:server:dialback".
307          */

308         invalid_namespace("invalid-namespace"),
309
310         /**
311          * The entity has sent invalid XML over the stream to a server that performs validation.
312          */

313         invalid_xml("invalid-xml"),
314
315         /**
316          * The entity has attempted to send data before the stream has been authenticated,
317          * or otherwise is not authorized to perform an action related to stream
318          * negotiation; the receiving entity MUST NOT process the offending stanza before
319          * sending the stream error.
320          */

321         not_authorized("not-authorized"),
322
323         /**
324          * The entity has violated some local service policy; the server MAY choose to
325          * specify the policy in the <text/> element or an application-specific condition
326          * element.
327          */

328         policy_violation("policy-violation"),
329
330         /**
331          * The server is unable to properly connect to a remote entity that is required for
332          * authentication or authorization.
333          */

334         remote_connection_failed("remote-connection-failed"),
335
336         /**
337          * The server lacks the system resources necessary to service the stream.
338          */

339         resource_constraint("resource-constraint"),
340
341         /**
342          * The entity has attempted to send restricted XML features such as a comment,
343          * processing instruction, DTD, entity reference, or unescaped character.
344          */

345         restricted_xml("restricted-xml"),
346
347         /**
348          * The server will not provide service to the initiating entity but is redirecting
349          * traffic to another host; the server SHOULD specify the alternate hostname or IP
350          * address (which MUST be a valid domain identifier) as the XML character data of the
351          * &lt;see-other-host/&gt; element.
352          */

353         see_other_host("see-other-host"),
354
355         /**
356          * The server is being shut down and all active streams are being closed.
357          */

358         system_shutdown("system-shutdown"),
359
360         /**
361          * The error condition is not one of those defined by the other conditions in this
362          * list; this error condition SHOULD be used only in conjunction with an
363          * application-specific condition.
364          */

365         undefined_condition("undefined-condition"),
366
367         /**
368          * The initiating entity has encoded the stream in an encoding that is not
369          * supported by the server.
370          */

371         unsupported_encoding("unsupported-encoding"),
372
373         /**
374          * The initiating entity has sent a first-level child of the stream that is
375          * not supported by the server.
376          */

377         unsupported_stanza_type("unsupported-stanza-type"),
378
379         /**
380          * the value of the 'version' attribute provided by the initiating entity in the
381          * stream header specifies a version of XMPP that is not supported by the server;
382          * the server MAY specify the version(s) it supports in the &lt;text/&gt; element.
383          */

384         unsupported_version("unsupported-version"),
385
386         /**
387          * The initiating entity has sent XML that is not well-formed.
388          */

389         xml_not_well_formed("xml-not-well-formed");
390
391         /**
392          * Converts a String value into its Condition representation.
393          *
394          * @param condition the String value.
395          * @return the condition corresponding to the String.
396          */

397         public static Condition fromXMPP(String JavaDoc condition) {
398             if (condition == null) {
399                 throw new NullPointerException JavaDoc();
400             }
401             condition = condition.toLowerCase();
402             if (bad_format.toXMPP().equals(condition)) {
403                 return bad_format;
404             }
405             else if (bad_namespace_prefix.toXMPP().equals(condition)) {
406                 return bad_namespace_prefix;
407             }
408             else if (conflict.toXMPP().equals(condition)) {
409                 return conflict;
410             }
411             else if (connection_timeout.toXMPP().equals(condition)) {
412                 return connection_timeout;
413             }
414             else if (host_gone.toXMPP().equals(condition)) {
415                 return host_gone;
416             }
417             else if (host_unknown.toXMPP().equals(condition)) {
418                 return host_unknown;
419             }
420             else if (improper_addressing.toXMPP().equals(condition)) {
421                 return improper_addressing;
422             }
423             else if (internal_server_error.toXMPP().equals(condition)) {
424                 return internal_server_error;
425             }
426             else if (invalid_from.toXMPP().equals(condition)) {
427                 return invalid_from;
428             }
429             else if (invalid_id.toXMPP().equals(condition)) {
430                 return invalid_id;
431             }
432             else if (invalid_namespace.toXMPP().equals(condition)) {
433                 return invalid_namespace;
434             }
435             else if (invalid_xml.toXMPP().equals(condition)) {
436                 return invalid_xml;
437             }
438             else if (not_authorized.toXMPP().equals(condition)) {
439                 return not_authorized;
440             }
441             else if (policy_violation.toXMPP().equals(condition)) {
442                 return policy_violation;
443             }
444             else if (remote_connection_failed.toXMPP().equals(condition)) {
445                 return remote_connection_failed;
446             }
447             else if (resource_constraint.toXMPP().equals(condition)) {
448                 return resource_constraint;
449             }
450             else if (restricted_xml.toXMPP().equals(condition)) {
451                 return restricted_xml;
452             }
453             else if (see_other_host.toXMPP().equals(condition)) {
454                 return see_other_host;
455             }
456             else if (system_shutdown.toXMPP().equals(condition)) {
457                 return system_shutdown;
458             }
459             else if (undefined_condition.toXMPP().equals(condition)) {
460                 return undefined_condition;
461             }
462             else if (unsupported_encoding.toXMPP().equals(condition)) {
463                 return unsupported_encoding;
464             }
465             else if (unsupported_stanza_type.toXMPP().equals(condition)) {
466                 return unsupported_stanza_type;
467             }
468             else if (unsupported_version.toXMPP().equals(condition)) {
469                 return unsupported_version;
470             }
471             else if (xml_not_well_formed.toXMPP().equals(condition)) {
472                 return xml_not_well_formed;
473             }
474             else {
475                 throw new IllegalArgumentException JavaDoc("Condition invalid:" + condition);
476             }
477         }
478
479         private String JavaDoc value;
480
481         private Condition(String JavaDoc value) {
482             this.value = value;
483         }
484
485         /**
486          * Returns the error code as a valid XMPP error code string.
487          *
488          * @return the XMPP error code value.
489          */

490         public String JavaDoc toXMPP() {
491             return value;
492         }
493     }
494 }
495
Popular Tags