KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > nu > xom > Attribute


1 /* Copyright 2002-2004 Elliotte Rusty Harold
2    
3    This library is free software; you can redistribute it and/or modify
4    it under the terms of version 2.1 of the GNU Lesser General Public
5    License as published by the Free Software Foundation.
6    
7    This library is distributed in the hope that it will be useful,
8    but WITHOUT ANY WARRANTY; without even the implied warranty of
9    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10    GNU Lesser General Public License for more details.
11    
12    You should have received a copy of the GNU Lesser General Public
13    License along with this library; if not, write to the
14    Free Software Foundation, Inc., 59 Temple Place, Suite 330,
15    Boston, MA 02111-1307 USA
16    
17    You can contact Elliotte Rusty Harold by sending e-mail to
18    elharo@metalab.unc.edu. Please include the word "XOM" in the
19    subject line. The XOM home page is located at http://www.xom.nu/
20 */

21
22 package nu.xom;
23
24 /**
25  * <p>
26  * This class represents an attribute such as
27  * <code>type="empty"</code> or
28  * <code>xlink:href="http://www.example.com"</code>.
29  * </p>
30  *
31  * <p>
32  * Attributes that declare namespaces such as
33  * <code>xmlns="http://www.w3.org/TR/1999/xhtml"</code>
34  * or <code>xmlns:xlink="http://www.w3.org/TR/1999/xlink"</code>
35  * are stored separately on the elements where they
36  * appear. They are never represented as <code>Attribute</code>
37  * objects.
38  * </p>
39  *
40  * @author Elliotte Rusty Harold
41  * @version 1.0
42  *
43  */

44 public class Attribute extends Node {
45     
46     private String JavaDoc localName;
47     private String JavaDoc prefix;
48     private String JavaDoc URI;
49     private String JavaDoc value = "";
50     private Type type;
51
52     
53     /**
54      * <p>
55      * Creates a new attribute in no namespace with the
56      * specified name and value and undeclared type.
57      * </p>
58      *
59      * @param localName the unprefixed attribute name
60      * @param value the attribute value
61      *
62      * @throws IllegalNameException if the local name is not
63      * a namespace well-formed, non-colonized name
64      * @throws IllegalDataException if the value contains characters
65      * which are not legal in XML such as vertical tab or a null.
66      * Characters such as " and &amp; are legal, but will be
67      * automatically escaped when the attribute is serialized.
68      */

69     public Attribute(String JavaDoc localName, String JavaDoc value) {
70         this(localName, "", value, Type.UNDECLARED);
71     }
72
73     
74     /**
75      * <p>
76      * Creates a new attribute in no namespace with the
77      * specified name, value, and type.
78      * </p>
79      *
80      * @param localName the unprefixed attribute name
81      * @param value the attribute value
82      * @param type the attribute type
83      *
84      * @throws IllegalNameException if the local name is
85      * not a namespace well-formed non-colonized name
86      * @throws IllegalDataException if the value contains
87      * characters which are not legal in
88      * XML such as vertical tab or a null. Note that
89      * characters such as " and &amp; are legal,
90      * but will be automatically escaped when the
91      * attribute is serialized.
92      */

93     public Attribute(String JavaDoc localName, String JavaDoc value, Type type) {
94         this(localName, "", value, type);
95     }
96
97     
98     /**
99      * <p>
100      * Creates a new attribute in the specified namespace with the
101      * specified name and value and undeclared type.
102      * </p>
103      *
104      * @param name the prefixed attribute name
105      * @param URI the namespace URI
106      * @param value the attribute value
107      *
108      * @throws IllegalNameException if the name is not a namespace
109      * well-formed prefixed name
110      * @throws IllegalDataException if the value contains characters
111      * which are not legal in XML such as vertical tab or a null.
112      * Note that characters such as " and &amp; are legal, but will
113      * be automatically escaped when the attribute is serialized.
114      * @throws MalformedURIException if <code>URI</code> is not
115      * an RFC2396 URI reference
116      */

117     public Attribute(String JavaDoc name, String JavaDoc URI, String JavaDoc value) {
118         this(name, URI, value, Type.UNDECLARED);
119     }
120
121     
122     /**
123      * <p>
124      * Creates a new attribute in the specified namespace with the
125      * specified name, value, and type.
126      * </p>
127      *
128      * @param name the prefixed attribute name
129      * @param URI the namespace URI
130      * @param value the attribute value
131      * @param type the attribute type
132      *
133      * @throws IllegalNameException if the name is not a namespace
134      * well-formed prefixed name
135      * @throws IllegalDataException if the value contains
136      * characters which are not legal in XML such as
137      * vertical tab or a null. Note that characters such as
138      * " and &amp; are legal, but will be automatically escaped
139      * when the attribute is serialized.
140      * @throws MalformedURIException if <code>URI</code> is not
141      * an RFC2396 absolute URI reference
142      */

143     public Attribute(
144       String JavaDoc name, String JavaDoc URI, String JavaDoc value, Type type) {
145
146         prefix = "";
147         String JavaDoc localName = name;
148         // Warning: do not cache the value returned by indexOf here
149
// and in build
150
// without profiling. My current tests show doing this slows
151
// down the parse by about 7%. I can't explain it.
152
if (name.indexOf(':') > 0) {
153             prefix = name.substring(0, name.indexOf(':'));
154             localName = name.substring(name.indexOf(':') + 1);
155         }
156
157         try {
158             _setLocalName(localName);
159         }
160         catch (IllegalNameException ex) {
161             ex.setData(name);
162             throw ex;
163         }
164         _setNamespace(prefix, URI);
165         _setValue(value);
166         _setType(type);
167         
168     }
169
170     
171     /**
172      * <p>
173      * Creates a copy of the specified attribute.
174      * </p>
175      *
176      * @param attribute the attribute to copy
177      *
178      */

179     public Attribute(Attribute attribute) {
180         
181         // These are all immutable types
182
this.localName = attribute.localName;
183         this.prefix = attribute.prefix;
184         this.URI = attribute.URI;
185         this.value = attribute.value;
186         this.type = attribute.type;
187         
188     }
189
190     
191     private Attribute() {}
192     
193     static Attribute build(
194       String JavaDoc name, String JavaDoc URI, String JavaDoc value, Type type) {
195         
196         Attribute result = new Attribute();
197     
198         String JavaDoc prefix = "";
199         String JavaDoc localName = name;
200         if (name.indexOf(':') >= 0) {
201             prefix = name.substring(0, name.indexOf(':'));
202             localName = name.substring(name.indexOf(':') + 1);
203         }
204         
205         result.localName = localName;
206         result.prefix = prefix;
207         result.type = type;
208         result.URI = URI;
209         result.value = value;
210         
211         return result;
212         
213     }
214
215
216     /**
217      * <p>
218      * Returns the DTD type of this attribute.
219      * If this attribute does not have a type, then
220      * <code>Type.UNDECLARED</code> is returned.
221      * </p>
222      *
223      * @return the DTD type of this attribute
224      */

225     public final Type getType() {
226         return type;
227     }
228
229     
230     /**
231      * <p>
232      * Sets the type of this attribute to one of the ten
233      * DTD types or <code>Type.UNDECLARED</code>.
234      * </p>
235      *
236      * @param type the DTD type of this attribute
237      */

238     public void setType(Type type) {
239         _setType(type);
240     }
241
242     
243     private void _setType(Type type) {
244         this.type = type;
245     }
246
247
248     /**
249      * <p>
250      * Returns the attribute value. If the attribute was
251      * originally created by a parser, it will have been
252      * normalized according to its type.
253      * However, attributes created in memory are not normalized.
254      * </p>
255      *
256      * @return the value of the attribute
257      *
258      */

259     public final String JavaDoc getValue() {
260         return value;
261     }
262
263     
264     /**
265      * <p>
266      * Sets the attribute's value to the specified string,
267      * replacing any previous value. The value is not normalized
268      * automatically.
269      * </p>
270      *
271      * @param value the value assigned to the attribute
272      * @throws IllegalDataException if the value contains characters
273      * which are not legal in XML such as vertical tab or a null.
274      * Characters such as " and &amp; are legal, but will be
275      * automatically escaped when the attribute is serialized.
276      * @throws MalformedURIException if this is an
277      * <code>xml:base</code> attribute, and the value is not a
278      * legal IRI
279      */

280     public void setValue(String JavaDoc value) {
281         _setValue(value);
282     }
283
284     
285     private void _setValue(String JavaDoc value) {
286         Verifier.checkPCDATA(value);
287         this.value = value;
288     }
289
290
291     /**
292      * <p>
293      * Returns the local name of this attribute,
294      * not including the prefix.
295      * </p>
296      *
297      * @return the attribute's local name
298      */

299     public final String JavaDoc getLocalName() {
300         return localName;
301     }
302
303     
304     /**
305      * <p>
306      * Sets the local name of the attribute.
307      * </p>
308      *
309      * @param localName the new local name
310      *
311      * @throws IllegalNameException if <code>localName</code>
312      * is not a namespace well-formed, non-colonized name
313      *
314      */

315     public void setLocalName(String JavaDoc localName) {
316         _setLocalName(localName);
317     }
318     
319     
320     private void _setLocalName(String JavaDoc localName) {
321         Verifier.checkNCName(localName);
322         if (localName.equals("xmlns")) {
323             throw new IllegalNameException("The Attribute class is not"
324               + " used for namespace declaration attributes.");
325         }
326         this.localName = localName;
327     }
328
329
330     /**
331      * <p>
332      * Returns the qualified name of this attribute,
333      * including the prefix if this attribute is in a namespace.
334      * </p>
335      *
336      * @return the attribute's qualified name
337      */

338     public final String JavaDoc getQualifiedName() {
339         if (prefix.length() == 0) return localName;
340         else return prefix + ":" + localName;
341     }
342     
343     
344     /**
345      * <p>
346      * Returns the namespace URI of this attribute, or the empty string
347      * if this attribute is not in a namespace.
348      * </p>
349      *
350      * @return the attribute's namespace URI
351      */

352     public final String JavaDoc getNamespaceURI() {
353         return URI;
354     }
355
356     
357     /**
358      * <p>
359      * Returns the prefix of this attribute,
360      * or the empty string if this attribute
361      * is not in a namespace.
362      * </p>
363      *
364      * @return the attribute's prefix
365      */

366     public final String JavaDoc getNamespacePrefix() {
367         return prefix;
368     }
369
370     
371     /**
372      * <p>
373      * Sets the attribute's namespace prefix and URI.
374      * Because attributes must be prefixed in order to have a
375      * namespace URI (and vice versa) this must be done
376      * simultaneously.
377      * </p>
378      *
379      * @param prefix the new namespace prefix
380      * @param URI the new namespace URI
381      *
382      * @throws MalformedURIException if <code>URI</code> is
383      * not an RFC2396 URI reference
384      * @throws IllegalNameException if
385      * <ul>
386      * <li>The prefix is <code>xmlns</code></li>
387      * <li>The prefix is null or the empty string.</li>
388      * <li>The URI is null or the empty string.</li>
389      * </ul>
390      * @throws NamespaceConflictException if
391      * <ul>
392      * <li>The prefix is <code>xml</code> and the namespace URI is
393      * not <code>http://www.w3.org/XML/1998/namespace</code></li>
394      * <li>The prefix conflicts with an existing declaration
395      * on the attribute's parent element.</li>
396      * </ul>
397      */

398     public void setNamespace(String JavaDoc prefix, String JavaDoc URI) {
399         _setNamespace(prefix, URI);
400     }
401
402     
403     private void _setNamespace(String JavaDoc prefix, String JavaDoc URI) {
404         
405         if (URI == null) URI = "";
406         if (prefix == null) prefix = "";
407         
408         if (prefix.equals("xmlns")) {
409             throw new IllegalNameException(
410               "Attribute objects are not used to represent "
411               + " namespace declarations");
412         }
413         else if (prefix.equals("xml")
414           && !(URI.equals("http://www.w3.org/XML/1998/namespace"))) {
415             throw new NamespaceConflictException(
416               "Wrong namespace URI for xml prefix: " + URI);
417         }
418         else if (URI.equals("http://www.w3.org/XML/1998/namespace")
419           && !prefix.equals("xml")) {
420             throw new NamespaceConflictException(
421               "Wrong prefix for the XML namespace: " + prefix);
422         }
423         else if (prefix.length() == 0) {
424             if (URI.length() == 0) {
425                 this.prefix = "";
426                 this.URI = "";
427                 return;
428             }
429             else {
430                 throw new NamespaceConflictException(
431                   "Unprefixed attribute " + this.localName
432                   + " cannot be in default namespace " + URI);
433             }
434         }
435         else if (URI.length() == 0) {
436             throw new NamespaceConflictException(
437              "Attribute prefixes must be declared.");
438         }
439         
440         ParentNode parent = this.getParent();
441         if (parent != null) {
442            // test for namespace conflicts
443
Element element = (Element) parent;
444            String JavaDoc currentURI = element.getLocalNamespaceURI(prefix);
445            if (currentURI != null && !currentURI.equals(URI)) {
446                 throw new NamespaceConflictException(
447                   "New prefix " + prefix
448                   + "conflicts with existing namespace declaration"
449                 );
450            }
451         }
452         
453         
454         Verifier.checkAbsoluteURIReference(URI);
455         Verifier.checkNCName(prefix);
456         
457         this.URI = URI;
458         this.prefix = prefix;
459         
460     }
461     
462     
463     /**
464      * <p>
465      * Throws <code>IndexOutOfBoundsException</code>
466      * because attributes do not have children.
467      * </p>
468      *
469      * @param position the child to return
470      *
471      * @return nothing. This method always throws an exception.
472      *
473      * @throws IndexOutOfBoundsException because attributes do
474      * not have children
475      */

476     public final Node getChild(int position) {
477         throw new IndexOutOfBoundsException JavaDoc(
478           "Attributes do not have children"
479         );
480     }
481
482     
483     /**
484      * <p>
485      * Returns 0 because attributes do not have children.
486      * </p>
487      *
488      * @return zero
489      */

490     public final int getChildCount() {
491         return 0;
492     }
493
494     
495     /**
496      * <p>
497      * Creates a deep copy of this attribute that
498      * is not attached to an element.
499      * </p>
500      *
501      * @return a copy of this attribute
502      *
503      */

504     public Node copy() {
505         return new Attribute(this);
506     }
507
508     
509     /**
510      * <p>
511      * Returns a string representation of the attribute
512      * that is a well-formed XML attribute.
513      * </p>
514      *
515      * @return a string containing the XML form of this attribute
516      */

517     public final String JavaDoc toXML() {
518         // It's a common belief that methods like this one should be
519
// implemented using StringBuffers rather than String
520
// concatenation for maximum performance. However,
521
// disassembling the code shows that today's compilers are
522
// smart enough to figure this out for themselves. The compiled
523
// version of this class only uses a single StringBuffer. No
524
// benefit would be gained by making the code more opaque here.
525
return getQualifiedName() + "=\"" + escapeText(value) + "\"";
526     }
527
528     
529     /**
530      * <p>
531      * Returns a string representation of the attribute suitable for
532      * debugging and diagnosis. However, this is not necessarily
533      * a well-formed XML attribute.
534      * </p>
535      *
536      * @return a non-XML string representation of this attribute
537      *
538      * @see java.lang.Object#toString()
539      */

540     public final String JavaDoc toString() {
541         return "[" + getClass().getName() + ": "
542          + getQualifiedName() + "=\""
543          + Text.escapeLineBreaksAndTruncate(getValue()) + "\"]";
544     }
545
546     
547     private static String JavaDoc escapeText(String JavaDoc s) {
548         
549         int length = s.length();
550         // Give the string buffer enough room for a couple of escaped characters
551
StringBuffer JavaDoc result = new StringBuffer JavaDoc(length+12);
552         for (int i = 0; i < length; i++) {
553             char c = s.charAt(i);
554             switch (c) {
555                 case '\t':
556                     result.append("&#x09;");
557                     break;
558                 case '\n':
559                     result.append("&#x0A;");
560                     break;
561                 case 11:
562                     // impossible
563
break;
564                 case 12:
565                     // impossible
566
break;
567                 case '\r':
568                     result.append("&#x0D;");
569                     break;
570                 case 14:
571                     // impossible
572
break;
573                 case 15:
574                     // impossible
575
break;
576                 case 16:
577                     // impossible
578
break;
579                 case 17:
580                     // impossible
581
break;
582                 case 18:
583                     // impossible
584
break;
585                 case 19:
586                     // impossible
587
break;
588                 case 20:
589                     // impossible
590
break;
591                 case 21:
592                     // impossible
593
break;
594                 case 22:
595                     // impossible
596
break;
597                 case 23:
598                     // impossible
599
break;
600                 case 24:
601                     // impossible
602
break;
603                 case 25:
604                     // impossible
605
break;
606                 case 26:
607                     // impossible
608
break;
609                 case 27:
610                     // impossible
611
break;
612                 case 28:
613                     // impossible
614
break;
615                 case 29:
616                     // impossible
617
break;
618                 case 30:
619                     // impossible
620
break;
621                 case 31:
622                     // impossible
623
break;
624                 case ' ':
625                     result.append(' ');
626                     break;
627                 case '!':
628                     result.append('!');
629                     break;
630                 case '"':
631                     result.append("&quot;");
632                     break;
633                 case '#':
634                     result.append('#');
635                     break;
636                 case '$':
637                     result.append('$');
638                     break;
639                 case '%':
640                     result.append('%');
641                     break;
642                 case '&':
643                     result.append("&amp;");
644                     break;
645                 case '\'':
646                     result.append('\'');
647                     break;
648                 case '(':
649                     result.append('(');
650                     break;
651                 case ')':
652                     result.append(')');
653                     break;
654                 case '*':
655                     result.append('*');
656                     break;
657                 case '+':
658                     result.append('+');
659                     break;
660                 case ',':
661                     result.append(',');
662                     break;
663                 case '-':
664                     result.append('-');
665                     break;
666                 case '.':
667                     result.append('.');
668                     break;
669                 case '/':
670                     result.append('/');
671                     break;
672                 case '0':
673                     result.append('0');
674                     break;
675                 case '1':
676                     result.append('1');
677                     break;
678                 case '2':
679                     result.append('2');
680                     break;
681                 case '3':
682                     result.append('3');
683                     break;
684                 case '4':
685                     result.append('4');
686                     break;
687                 case '5':
688                     result.append('5');
689                     break;
690                 case '6':
691                     result.append('6');
692                     break;
693                 case '7':
694                     result.append('7');
695                     break;
696                 case '8':
697                     result.append('8');
698                     break;
699                 case '9':
700                     result.append('9');
701                     break;
702                 case ':':
703                     result.append(':');
704                     break;
705                 case ';':
706                     result.append(';');
707                     break;
708                 case '<':
709                     result.append("&lt;");
710                     break;
711                 case '=':
712                     result.append('=');
713                     break;
714                 case '>':
715                     result.append("&gt;");
716                     break;
717                 default:
718                     result.append(c);
719             }
720         }
721         return result.toString();
722         
723     }
724
725     
726     boolean isAttribute() {
727         return true;
728     }
729     
730     
731     /**
732      * <p>
733      * Uses the type-safe enumeration
734      * design pattern to represent attribute types,
735      * as specified by XML DTDs.
736      * </p>
737      *
738      * <p>
739      * XOM enforces well-formedness, but it does not enforce
740      * validity. Thus it is possible for a single element to have
741      * multiple ID type attributes, or ID type attributes
742      * on different elements to have the same value,
743      * or NMTOKEN type attributes that don't contain legal
744      * XML name tokens, and so forth.
745      * </p>
746      *
747      * @author Elliotte Rusty Harold
748      * @version 1.0
749      *
750      */

751     public static final class Type {
752
753         /**
754          * <p>
755          * The type of attributes declared to have type CDATA
756          * in the DTD. The most general attribute type.
757          * All well-formed attribute values are valid for
758          * attributes of type CDATA.
759          * </p>
760          */

761         public static final Type CDATA = new Type(1);
762
763         /**
764          * <p>
765          * The type of attributes declared to have type ID
766          * in the DTD. In order to be valid, an ID type attribute
767          * must contain an XML name which is unique among other
768          * ID type attributes in the document.
769          * Furthermore, each element may contain no more than one
770          * ID type attribute. However, XOM does not enforce
771          * such validity constraints.
772          * </p>
773          */

774         public static final Type ID = new Type(2);
775         
776         /**
777          * <p>
778          * The type of attributes declared to have type IDREF
779          * in the DTD. In order to be valid, an IDREF type attribute
780          * must contain an XML name which is also the value of
781          * ID type attribute of some element in the document.
782          * However, XOM does not enforce such validity constraints.
783          * </p>
784          *
785          */

786         public static final Type IDREF = new Type(3);
787
788         /**
789          * <p>
790          * The type of attributes declared to have type IDREFS
791          * in the DTD. In order to be valid, an IDREFS type attribute
792          * must contain a white space separated list of
793          * XML names, each of which is also the value of
794          * ID type attribute of some element in the document.
795          * However, XOM does not enforce such validity constraints.
796          * </p>
797          *
798          */

799         public static final Type IDREFS = new Type(4);
800
801         /**
802          * <p>
803          * The type of attributes declared to have type NMTOKEN
804          * in the DTD. In order to be valid, a NMTOKEN type
805          * attribute must contain a single XML name token. However,
806          * XOM does not enforce such validity constraints.
807          * </p>
808          *
809          */

810         public static final Type NMTOKEN = new Type(5);
811
812         /**
813          * <p>
814          * The type of attributes declared to have type NMTOKENS
815          * in the DTD. In order to be valid, a NMTOKENS type attribute
816          * must contain a white space separated list of XML name
817          * tokens. However, XOM does not enforce such validity
818          * constraints.
819          * </p>
820          *
821          */

822         public static final Type NMTOKENS = new Type(6);
823
824
825         /**
826          * <p>
827          * The type of attributes declared to have type NOTATION
828          * in the DTD. In order to be valid, a NOTATION type
829          * attribute must contain the name of a notation declared
830          * in the DTD. However, XOM does not enforce such
831          * validity constraints.
832          * </p>
833           *
834          */

835         public static final Type NOTATION = new Type(7);
836
837         /**
838          * <p>
839          * The type of attributes declared to have type ENTITY
840          * in the DTD. In order to be valid, a ENTITY type attribute
841          * must contain the name of an unparsed entity declared in
842          * the DTD. However, XOM does not enforce such
843          * validity constraints.
844          * </p>
845          *
846          */

847         public static final Type ENTITY = new Type(8);
848
849         /**
850          * <p>
851          * The type of attributes declared to have type ENTITIES
852          * in the DTD. In order to be valid, an ENTITIES type
853          * attribute must contain a white space separated list of
854          * names of unparsed entities declared in the DTD.
855          * However, XOM does not enforce such validity constraints.
856          * </p>
857          *
858          */

859         public static final Type ENTITIES = new Type(9);
860
861         /**
862          * <p>
863          * The type of attributes declared by an enumeration
864          * in the DTD. In order to be valid, a enumeration type
865          * attribute must contain exactly one of the names given
866          * in the enumeration in the DTD. However, XOM does not
867          * enforce such validity constraints.
868          * </p>
869          *
870          * <p>
871          * Most parsers report attributes of type enumeration as
872          * having type NMTOKEN. In this case, XOM will not
873          * distinguish NMTOKEN and enumerated attributes.
874          * </p>
875          *
876          */

877         public static final Type ENUMERATION = new Type(10);
878         
879         /**
880          * <p>
881          * The type of attributes not declared in the DTD.
882          * This type only appears in invalid documents.
883          * This is the default type for all attributes in
884          * documents without DTDs.
885          * </p>
886          *
887          * <p>
888          * Most parsers report attributes of undeclared
889          * type as having type CDATA. In this case, XOM
890          * will not distinguish CDATA and undeclared attributes.
891          * </p>
892          */

893         public static final Type UNDECLARED = new Type(0);
894
895         
896         /**
897          * <p>
898          * Returns the string name of this type as might
899          * be used in a DTD; for example, "ID", "CDATA", etc.
900          * </p>
901          *
902          * @return an XML string representation of this type
903          */

904         public String JavaDoc getName() {
905             
906             switch (type) {
907               case 0:
908                 return "UNDECLARED";
909               case 1:
910                 return "CDATA";
911               case 2:
912                 return "ID";
913               case 3:
914                 return "IDREF";
915               case 4:
916                 return "IDREFS";
917               case 5:
918                 return "NMTOKEN";
919               case 6:
920                 return "NMTOKENS";
921               case 7:
922                 return "NOTATION";
923               case 8:
924                 return "ENTITY";
925               case 9:
926                 return "ENTITIES";
927               case 10:
928                 return "ENUMERATION";
929               default:
930                 throw new RuntimeException JavaDoc(
931                   "Bug in XOM: unexpected attribute type: " + type);
932             }
933             
934         }
935
936
937         private int type;
938
939         private Type(int type) {
940           this.type = type;
941         }
942         
943         
944         /**
945          * <p>
946          * Returns a unique identifier for this type.
947          * </p>
948          *
949          * @return a unique identifier for this type
950          *
951          * @see java.lang.Object#hashCode()
952          */

953         public int hashCode() {
954             return this.type;
955         }
956         
957         
958         /**
959          * <p>
960          * Tests for type equality. This is only necessary,
961          * to handle the case where two <code>Type</code> objects
962          * are loaded by different class loaders.
963          * </p>
964          *
965          * @param o the object compared for equality to this type
966          *
967          * @return true if and only if <code>o</code> represents
968          * the same type
969          *
970          * @see java.lang.Object#equals(Object)
971          */

972         public boolean equals(Object JavaDoc o) {
973             
974             if (o == this) return true;
975             if (o == null) return false;
976             if (this.hashCode() != o.hashCode()) return false;
977             if (!o.getClass().getName().equals("nu.xom.Attribute.Type")) {
978                 return false;
979             }
980             return true;
981             
982         }
983         
984         
985         /**
986          * <p>
987          * Returns a string representation of the type
988          * suitable for debugging and diagnosis.
989          * </p>
990          *
991          * @return a non-XML string representation of this type
992          *
993          * @see java.lang.Object#toString()
994          */

995          public String JavaDoc toString() {
996              
997             StringBuffer JavaDoc result
998               = new StringBuffer JavaDoc("[Attribute.Type: ");
999             result.append(getName());
1000            result.append("]");
1001            return result.toString();
1002            
1003        }
1004
1005         
1006    }
1007
1008    
1009}
1010
Popular Tags