View Javadoc

1   /*
2    * Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
3    *
4    * This software is open source.
5    * See the bottom of this file for the licence.
6    */
7   
8   package org.dom4j;
9   
10  import java.util.Iterator;
11  import java.util.List;
12  import java.util.Map;
13  
14  /***
15   * <p>
16   * <code>Element</code> interface defines an XML element. An element can have
17   * declared namespaces, attributes, child nodes and textual content.
18   * </p>
19   * 
20   * <p>
21   * Some of this interface is optional. Some implementations may be read-only and
22   * not support being modified. Some implementations may not support the parent
23   * relationship and methods such as {@link #getParent}or {@link#getDocument}.
24   * </p>
25   * 
26   * @author <a href="mailto:jstrachan@apache.org">James Strachan </a>
27   * @version $Revision: 1.47 $
28   */
29  public interface Element extends Branch {
30      // Name and namespace related methods
31      // -------------------------------------------------------------------------
32  
33      /***
34       * <p>
35       * Returns the <code>QName</code> of this element which represents the
36       * local name, the qualified name and the <code>Namespace</code>.
37       * </p>
38       * 
39       * @return the <code>QName</code> associated with this element
40       */
41      QName getQName();
42  
43      /***
44       * <p>
45       * Sets the <code>QName</code> of this element which represents the local
46       * name, the qualified name and the <code>Namespace</code>.
47       * </p>
48       * 
49       * @param qname
50       *            is the <code>QName</code> to be associated with this element
51       */
52      void setQName(QName qname);
53  
54      /***
55       * <p>
56       * Returns the <code>Namespace</code> of this element if one exists
57       * otherwise <code>Namespace.NO_NAMESPACE</code> is returned.
58       * </p>
59       * 
60       * @return the <code>Namespace</code> associated with this element
61       */
62      Namespace getNamespace();
63  
64      /***
65       * <p>
66       * Returns the <code>QName</code> for the given qualified name, using the
67       * namespace URI in scope for the given prefix of the qualified name or the
68       * default namespace if the qualified name has no prefix.
69       * </p>
70       * 
71       * @param qualifiedName
72       *            DOCUMENT ME!
73       * 
74       * @return the <code>QName</code> for the given qualified name
75       */
76      QName getQName(String qualifiedName);
77  
78      /***
79       * <p>
80       * Returns the <code>Namespace</code> which is mapped to the given prefix
81       * or null if it could not be found.
82       * </p>
83       * 
84       * @param prefix
85       *            DOCUMENT ME!
86       * 
87       * @return the <code>Namespace</code> associated with the given prefix
88       */
89      Namespace getNamespaceForPrefix(String prefix);
90  
91      /***
92       * <p>
93       * Returns the <code>Namespace</code> which is mapped to the given URI or
94       * null if it could not be found. If there is more than one
95       * <code>Namespace</code> mapped to the URI, which of them will be
96       * returned is undetermined.
97       * </p>
98       * 
99       * @param uri
100      *            DOCUMENT ME!
101      * 
102      * @return the <code>Namespace</code> associated with the given URI
103      */
104     Namespace getNamespaceForURI(String uri);
105 
106     /***
107      * <p>
108      * Returns the all namespaces which are mapped to the given URI or an empty
109      * list if no such namespaces could be found.
110      * </p>
111      * 
112      * @param uri
113      *            DOCUMENT ME!
114      * 
115      * @return the namespaces associated with the given URI
116      * 
117      * @since 1.5
118      */
119     List getNamespacesForURI(String uri);
120 
121     /***
122      * <p>
123      * Returns the namespace prefix of this element if one exists otherwise an
124      * empty <code>String</code> is returned.
125      * </p>
126      * 
127      * @return the prefix of the <code>Namespace</code> of this element or an
128      *         empty <code>String</code>
129      */
130     String getNamespacePrefix();
131 
132     /***
133      * <p>
134      * Returns the URI mapped to the namespace of this element if one exists
135      * otherwise an empty <code>String</code> is returned.
136      * </p>
137      * 
138      * @return the URI for the <code>Namespace</code> of this element or an
139      *         empty <code>String</code>
140      */
141     String getNamespaceURI();
142 
143     /***
144      * <p>
145      * Returns the fully qualified name of this element. This will be the same
146      * as the value returned from {@link #getName}if this element has no
147      * namespace attached to this element or an expression of the form
148      * 
149      * <pre>
150      * getNamespacePrefix() + &quot;:&quot; + getName()
151      * </pre>
152      * 
153      * will be returned.
154      * </p>
155      * 
156      * @return the fully qualified name of the element.
157      */
158     String getQualifiedName();
159 
160     /***
161      * <p>
162      * Returns any additional namespaces declarations for this element other
163      * than namespace returned via the {@link #getNamespace()}method. If no
164      * additional namespace declarations are present for this element then an
165      * empty list will be returned. The list is backed by the element such that
166      * changes to the list will be reflected in the element though the reverse
167      * is not the case.
168      * </p>
169      * 
170      * @return a list of any additional namespace declarations.
171      */
172     List additionalNamespaces();
173 
174     /***
175      * <p>
176      * Returns all the namespaces declared by this element. If no namespaces are
177      * declared for this element then an empty list will be returned. The list
178      * is backed by the element such that changes to the list will be reflected
179      * in the element though the reverse is not the case.
180      * </p>
181      * 
182      * @return a list of namespaces declared for this element.
183      */
184     List declaredNamespaces();
185 
186     // Builder methods
187     // -------------------------------------------------------------------------
188 
189     /***
190      * <p>
191      * Adds the attribute value of the given local name. If an attribute already
192      * exists for the given name it will be replaced. Attributes with null
193      * values are silently ignored. If the value of the attribute is null then
194      * this method call will remove any attributes with the given name.
195      * </p>
196      * 
197      * @param name
198      *            is the name of the attribute whose value is to be added or
199      *            updated
200      * @param value
201      *            is the attribute's value
202      * 
203      * @return this <code>Element</code> instance.
204      */
205     Element addAttribute(String name, String value);
206 
207     /***
208      * <p>
209      * Adds the attribute value of the given fully qualified name. If an
210      * attribute already exists for the given name it will be replaced.
211      * Attributes with null values are silently ignored. If the value of the
212      * attribute is null then this method call will remove any attributes with
213      * the given name.
214      * </p>
215      * 
216      * @param qName
217      *            is the fully qualified name of the attribute whose value is to
218      *            be added or updated
219      * @param value
220      *            is the attribute's value
221      * 
222      * @return this <code>Element</code> instance.
223      */
224     Element addAttribute(QName qName, String value);
225 
226     /***
227      * Adds a new <code>Comment</code> node with the given text to this
228      * element.
229      * 
230      * @param comment
231      *            is the text for the <code>Comment</code> node.
232      * 
233      * @return this <code>Element</code> instance.
234      */
235     Element addComment(String comment);
236 
237     /***
238      * Adds a new <code>CDATA</code> node with the given text to this element.
239      * 
240      * @param cdata
241      *            is the text for the <code>CDATA</code> node.
242      * 
243      * @return this <code>Element</code> instance.
244      */
245     Element addCDATA(String cdata);
246 
247     /***
248      * Adds a new <code>Entity</code> node with the given name and text to
249      * this element and returns a reference to the new node.
250      * 
251      * @param name
252      *            is the name for the <code>Entity</code> node.
253      * @param text
254      *            is the text for the <code>Entity</code> node.
255      * 
256      * @return this <code>Element</code> instance.
257      */
258     Element addEntity(String name, String text);
259 
260     /***
261      * Adds a namespace to this element for use by its child content
262      * 
263      * @param prefix
264      *            is the prefix to use, which should not be null or blank
265      * @param uri
266      *            is the namespace URI
267      * 
268      * @return this <code>Element</code> instance.
269      */
270     Element addNamespace(String prefix, String uri);
271 
272     /***
273      * Adds a processing instruction for the given target
274      * 
275      * @param target
276      *            is the target of the processing instruction
277      * @param text
278      *            is the textual data (key/value pairs) of the processing
279      *            instruction
280      * 
281      * @return this <code>Element</code> instance.
282      */
283     Element addProcessingInstruction(String target, String text);
284 
285     /***
286      * Adds a processing instruction for the given target
287      * 
288      * @param target
289      *            is the target of the processing instruction
290      * @param data
291      *            is a Map of the key / value pairs of the processing
292      *            instruction
293      * 
294      * @return this <code>Element</code> instance.
295      */
296     Element addProcessingInstruction(String target, Map data);
297 
298     /***
299      * Adds a new <code>Text</code> node with the given text to this element.
300      * 
301      * @param text
302      *            is the text for the <code>Text</code> node.
303      * 
304      * @return this <code>Element</code> instance.
305      */
306     Element addText(String text);
307 
308     // Typesafe modifying methods
309     // -------------------------------------------------------------------------
310 
311     /***
312      * Adds the given <code>Attribute</code> to this element. If the given
313      * node already has a parent defined then an
314      * <code>IllegalAddException</code> will be thrown. Attributes with null
315      * values are silently ignored.
316      * 
317      * <p>
318      * If the value of the attribute is null then this method call will remove
319      * any attributes with the QName of this attribute.
320      * </p>
321      * 
322      * @param attribute
323      *            is the attribute to be added
324      */
325     void add(Attribute attribute);
326 
327     /***
328      * Adds the given <code>CDATA</code> to this element. If the given node
329      * already has a parent defined then an <code>IllegalAddException</code>
330      * will be thrown.
331      * 
332      * @param cdata
333      *            is the CDATA to be added
334      */
335     void add(CDATA cdata);
336 
337     /***
338      * Adds the given <code>Entity</code> to this element. If the given node
339      * already has a parent defined then an <code>IllegalAddException</code>
340      * will be thrown.
341      * 
342      * @param entity
343      *            is the entity to be added
344      */
345     void add(Entity entity);
346 
347     /***
348      * Adds the given <code>Text</code> to this element. If the given node
349      * already has a parent defined then an <code>IllegalAddException</code>
350      * will be thrown.
351      * 
352      * @param text
353      *            is the text to be added
354      */
355     void add(Text text);
356 
357     /***
358      * Adds the given <code>Namespace</code> to this element. If the given
359      * node already has a parent defined then an
360      * <code>IllegalAddException</code> will be thrown.
361      * 
362      * @param namespace
363      *            is the namespace to be added
364      */
365     void add(Namespace namespace);
366 
367     /***
368      * Removes the given <code>Attribute</code> from this element.
369      * 
370      * @param attribute
371      *            is the attribute to be removed
372      * 
373      * @return true if the attribute was removed
374      */
375     boolean remove(Attribute attribute);
376 
377     /***
378      * Removes the given <code>CDATA</code> if the node is an immediate child
379      * of this element. If the given node is not an immediate child of this
380      * element then the {@link Node#detach()}method should be used instead.
381      * 
382      * @param cdata
383      *            is the CDATA to be removed
384      * 
385      * @return true if the cdata was removed
386      */
387     boolean remove(CDATA cdata);
388 
389     /***
390      * Removes the given <code>Entity</code> if the node is an immediate child
391      * of this element. If the given node is not an immediate child of this
392      * element then the {@link Node#detach()}method should be used instead.
393      * 
394      * @param entity
395      *            is the entity to be removed
396      * 
397      * @return true if the entity was removed
398      */
399     boolean remove(Entity entity);
400 
401     /***
402      * Removes the given <code>Namespace</code> if the node is an immediate
403      * child of this element. If the given node is not an immediate child of
404      * this element then the {@link Node#detach()}method should be used
405      * instead.
406      * 
407      * @param namespace
408      *            is the namespace to be removed
409      * 
410      * @return true if the namespace was removed
411      */
412     boolean remove(Namespace namespace);
413 
414     /***
415      * Removes the given <code>Text</code> if the node is an immediate child
416      * of this element. If the given node is not an immediate child of this
417      * element then the {@link Node#detach()}method should be used instead.
418      * 
419      * @param text
420      *            is the text to be removed
421      * 
422      * @return true if the text was removed
423      */
424     boolean remove(Text text);
425 
426     // Text methods
427     // -------------------------------------------------------------------------
428 
429     /***
430      * Returns the text value of this element without recursing through child
431      * elements. This method iterates through all {@link Text},{@link CDATA}
432      * and {@link Entity}nodes that this element contains and appends the text
433      * values together.
434      * 
435      * @return the textual content of this Element. Child elements are not
436      *         navigated. This method does not return null;
437      */
438     String getText();
439 
440     /***
441      * DOCUMENT ME!
442      * 
443      * @return the trimmed text value where whitespace is trimmed and normalised
444      *         into single spaces. This method does not return null.
445      */
446     String getTextTrim();
447 
448     /***
449      * Returns the XPath string-value of this node. The behaviour of this method
450      * is defined in the <a href="http://www.w3.org/TR/xpath">XPath
451      * specification </a>. This method returns the string-value of all the
452      * contained {@link Text},{@link CDATA},{@link Entity}and {@link
453      * Element} nodes all appended together.
454      * 
455      * @return the text from all the child Text and Element nodes appended
456      *         together.
457      */
458     String getStringValue();
459 
460     /***
461      * Accesses the data of this element which may implement data typing
462      * bindings such as XML Schema or Java Bean bindings or will return the same
463      * value as {@link #getText}
464      * 
465      * @return DOCUMENT ME!
466      */
467     Object getData();
468 
469     /***
470      * Sets the data value of this element if this element supports data binding
471      * or calls {@link #setText}if it doesn't
472      * 
473      * @param data
474      *            DOCUMENT ME!
475      */
476     void setData(Object data);
477 
478     // Attribute methods
479     // -------------------------------------------------------------------------
480 
481     /***
482      * <p>
483      * Returns the {@link Attribute}instances this element contains as a backed
484      * {@link List}so that the attributes may be modified directly using the
485      * {@link List}interface. The <code>List</code> is backed by the
486      * <code>Element</code> so that changes to the list are reflected in the
487      * element and vice versa.
488      * </p>
489      * 
490      * @return the attributes that this element contains as a <code>List</code>
491      */
492     List attributes();
493 
494     /***
495      * Sets the attributes that this element contains
496      * 
497      * @param attributes
498      *            DOCUMENT ME!
499      */
500     void setAttributes(List attributes);
501 
502     /***
503      * DOCUMENT ME!
504      * 
505      * @return the number of attributes this element contains
506      */
507     int attributeCount();
508 
509     /***
510      * DOCUMENT ME!
511      * 
512      * @return an iterator over the attributes of this element
513      */
514     Iterator attributeIterator();
515 
516     /***
517      * Returns the attribute at the specified indexGets the
518      * 
519      * @param index
520      *            DOCUMENT ME!
521      * 
522      * @return the attribute at the specified index where index &gt;= 0 and
523      *         index &lt; number of attributes or throws an
524      *         IndexOutOfBoundsException if the index is not within the
525      *         allowable range
526      */
527     Attribute attribute(int index);
528 
529     /***
530      * Returns the attribute with the given name
531      * 
532      * @param name
533      *            DOCUMENT ME!
534      * 
535      * @return the attribute for the given local name in any namespace. If there
536      *         are more than one attributes with the given local name in
537      *         different namespaces then the first one is returned.
538      */
539     Attribute attribute(String name);
540 
541     /***
542      * DOCUMENT ME!
543      * 
544      * @param qName
545      *            is the fully qualified name
546      * 
547      * @return the attribute for the given fully qualified name or null if it
548      *         could not be found.
549      */
550     Attribute attribute(QName qName);
551 
552     /***
553      * <p>
554      * This returns the attribute value for the attribute with the given name
555      * and any namespace or null if there is no such attribute or the empty
556      * string if the attribute value is empty.
557      * </p>
558      * 
559      * @param name
560      *            is the name of the attribute value to be returnd
561      * 
562      * @return the value of the attribute, null if the attribute does not exist
563      *         or the empty string
564      */
565     String attributeValue(String name);
566 
567     /***
568      * <p>
569      * This returns the attribute value for the attribute with the given name
570      * and any namespace or the default value if there is no such attribute
571      * value.
572      * </p>
573      * 
574      * @param name
575      *            is the name of the attribute value to be returnd
576      * @param defaultValue
577      *            is the default value to be returned if the attribute has no
578      *            value defined.
579      * 
580      * @return the value of the attribute or the defaultValue if the attribute
581      *         has no value defined.
582      */
583     String attributeValue(String name, String defaultValue);
584 
585     /***
586      * <p>
587      * This returns the attribute value for the attribute with the given fully
588      * qualified name or null if there is no such attribute or the empty string
589      * if the attribute value is empty.
590      * </p>
591      * 
592      * @param qName
593      *            is the fully qualified name
594      * 
595      * @return the value of the attribute, null if the attribute does not exist
596      *         or the empty string
597      */
598     String attributeValue(QName qName);
599 
600     /***
601      * <p>
602      * This returns the attribute value for the attribute with the given fully
603      * qualified name or the default value if there is no such attribute value.
604      * </p>
605      * 
606      * @param qName
607      *            is the fully qualified name
608      * @param defaultValue
609      *            is the default value to be returned if the attribute has no
610      *            value defined.
611      * 
612      * @return the value of the attribute or the defaultValue if the attribute
613      *         has no value defined.
614      */
615     String attributeValue(QName qName, String defaultValue);
616 
617     /***
618      * <p>
619      * Sets the attribute value of the given local name.
620      * </p>
621      * 
622      * @param name
623      *            is the name of the attribute whose value is to be added or
624      *            updated
625      * @param value
626      *            is the attribute's value
627      * 
628      * @deprecated As of version 0.5. Please use {@link
629      *             #addAttribute(String,String)} instead. WILL BE REMOVED IN
630      *             dom4j-1.6 !!
631      */
632     void setAttributeValue(String name, String value);
633 
634     /***
635      * <p>
636      * Sets the attribute value of the given fully qualified name.
637      * </p>
638      * 
639      * @param qName
640      *            is the fully qualified name of the attribute whose value is to
641      *            be added or updated
642      * @param value
643      *            is the attribute's value
644      * 
645      * @deprecated As of version 0.5. Please use {@link
646      *             #addAttribute(QName,String)} instead. WILL BE REMOVED IN
647      *             dom4j-1.6 !!
648      */
649     void setAttributeValue(QName qName, String value);
650 
651     // Content methods
652     // -------------------------------------------------------------------------
653 
654     /***
655      * Returns the first element for the given local name and any namespace.
656      * 
657      * @param name
658      *            DOCUMENT ME!
659      * 
660      * @return the first element with the given local name
661      */
662     Element element(String name);
663 
664     /***
665      * Returns the first element for the given fully qualified name.
666      * 
667      * @param qName
668      *            is the fully qualified name to search for
669      * 
670      * @return the first element with the given fully qualified name
671      */
672     Element element(QName qName);
673 
674     /***
675      * <p>
676      * Returns the elements contained in this element. If this element does not
677      * contain any elements then this method returns an empty list. The list is
678      * backed by the element such that changes to the list will be reflected in
679      * the element though the reverse is not the case.
680      * </p>
681      * 
682      * @return a list of all the elements in this element.
683      */
684     List elements();
685 
686     /***
687      * <p>
688      * Returns the elements contained in this element with the given local name
689      * and any namespace. If no elements are found then this method returns an
690      * empty list. The list is backed by the element such that changes to the
691      * list will be reflected in the element though the reverse is not the case.
692      * </p>
693      * 
694      * @param name
695      *            DOCUMENT ME!
696      * 
697      * @return a list of all the elements in this element for the given local
698      *         name
699      */
700     List elements(String name);
701 
702     /***
703      * <p>
704      * Returns the elements contained in this element with the given fully
705      * qualified name. If no elements are found then this method returns an
706      * empty list. The list is backed by the element such that changes to the
707      * list will be reflected in the element though the reverse is not the case.
708      * </p>
709      * 
710      * @param qName
711      *            is the fully qualified name to search for
712      * 
713      * @return a list of all the elements in this element for the given fully
714      *         qualified name.
715      */
716     List elements(QName qName);
717 
718     /***
719      * Returns an iterator over all this elements child elements.
720      * 
721      * @return an iterator over the contained elements
722      */
723     Iterator elementIterator();
724 
725     /***
726      * Returns an iterator over the elements contained in this element which
727      * match the given local name and any namespace.
728      * 
729      * @param name
730      *            DOCUMENT ME!
731      * 
732      * @return an iterator over the contained elements matching the given local
733      *         name
734      */
735     Iterator elementIterator(String name);
736 
737     /***
738      * Returns an iterator over the elements contained in this element which
739      * match the given fully qualified name.
740      * 
741      * @param qName
742      *            is the fully qualified name to search for
743      * 
744      * @return an iterator over the contained elements matching the given fully
745      *         qualified name
746      */
747     Iterator elementIterator(QName qName);
748 
749     // Helper methods
750     // -------------------------------------------------------------------------
751 
752     /***
753      * DOCUMENT ME!
754      * 
755      * @return true if this element is the root element of a document and this
756      *         element supports the parent relationship else false.
757      */
758     boolean isRootElement();
759 
760     /***
761      * <p>
762      * Returns true if this <code>Element</code> has mixed content. Mixed
763      * content means that an element contains both textual data and child
764      * elements.
765      * </p>
766      * 
767      * @return true if this element contains mixed content.
768      */
769     boolean hasMixedContent();
770 
771     /***
772      * <p>
773      * Returns true if this <code>Element</code> has text only content.
774      * </p>
775      * 
776      * @return true if this element is empty or only contains text content.
777      */
778     boolean isTextOnly();
779 
780     /***
781      * Appends the attributes of the given element to me. This method behaves
782      * like the {@link java.util.Collection#addAll(java.util.Collection)}
783      * method.
784      * 
785      * @param element
786      *            is the element whose attributes will be added to me.
787      */
788     void appendAttributes(Element element);
789 
790     /***
791      * <p>
792      * Creates a deep copy of this element The new element is detached from its
793      * parent, and getParent() on the clone will return null.
794      * </p>
795      * 
796      * @return a new deep copy Element
797      */
798     Element createCopy();
799 
800     /***
801      * <p>
802      * Creates a deep copy of this element with the given local name The new
803      * element is detached from its parent, and getParent() on the clone will
804      * return null.
805      * </p>
806      * 
807      * @param name
808      *            DOCUMENT ME!
809      * 
810      * @return a new deep copy Element
811      */
812     Element createCopy(String name);
813 
814     /***
815      * <p>
816      * Creates a deep copy of this element with the given fully qualified name.
817      * The new element is detached from its parent, and getParent() on the clone
818      * will return null.
819      * </p>
820      * 
821      * @param qName
822      *            DOCUMENT ME!
823      * 
824      * @return a new deep copy Element
825      */
826     Element createCopy(QName qName);
827 
828     String elementText(String name);
829 
830     String elementText(QName qname);
831 
832     String elementTextTrim(String name);
833 
834     String elementTextTrim(QName qname);
835 
836     /***
837      * Returns a node at the given index suitable for an XPath result set. This
838      * means the resulting Node will either be null or it will support the
839      * parent relationship.
840      * 
841      * @param index
842      *            DOCUMENT ME!
843      * 
844      * @return the Node for the given index which will support the parent
845      *         relationship or null if there is not a node at the given index.
846      */
847     Node getXPathResult(int index);
848 }
849 
850 /*
851  * Redistribution and use of this software and associated documentation
852  * ("Software"), with or without modification, are permitted provided that the
853  * following conditions are met:
854  * 
855  * 1. Redistributions of source code must retain copyright statements and
856  * notices. Redistributions must also contain a copy of this document.
857  * 
858  * 2. Redistributions in binary form must reproduce the above copyright notice,
859  * this list of conditions and the following disclaimer in the documentation
860  * and/or other materials provided with the distribution.
861  * 
862  * 3. The name "DOM4J" must not be used to endorse or promote products derived
863  * from this Software without prior written permission of MetaStuff, Ltd. For
864  * written permission, please contact dom4j-info@metastuff.com.
865  * 
866  * 4. Products derived from this Software may not be called "DOM4J" nor may
867  * "DOM4J" appear in their names without prior written permission of MetaStuff,
868  * Ltd. DOM4J is a registered trademark of MetaStuff, Ltd.
869  * 
870  * 5. Due credit should be given to the DOM4J Project - http://www.dom4j.org
871  * 
872  * THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS ``AS IS'' AND
873  * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
874  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
875  * ARE DISCLAIMED. IN NO EVENT SHALL METASTUFF, LTD. OR ITS CONTRIBUTORS BE
876  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
877  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
878  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
879  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
880  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
881  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
882  * POSSIBILITY OF SUCH DAMAGE.
883  * 
884  * Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
885  */