0
|
1 /*--
|
|
2
|
|
3 $Id: Attribute.java,v 1.56 2007/11/10 05:28:58 jhunter Exp $
|
|
4
|
|
5 Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin.
|
|
6 All rights reserved.
|
|
7
|
|
8 Redistribution and use in source and binary forms, with or without
|
|
9 modification, are permitted provided that the following conditions
|
|
10 are met:
|
|
11
|
|
12 1. Redistributions of source code must retain the above copyright
|
|
13 notice, this list of conditions, and the following disclaimer.
|
|
14
|
|
15 2. Redistributions in binary form must reproduce the above copyright
|
|
16 notice, this list of conditions, and the disclaimer that follows
|
|
17 these conditions in the documentation and/or other materials
|
|
18 provided with the distribution.
|
|
19
|
|
20 3. The name "JDOM" must not be used to endorse or promote products
|
|
21 derived from this software without prior written permission. For
|
|
22 written permission, please contact <request_AT_jdom_DOT_org>.
|
|
23
|
|
24 4. Products derived from this software may not be called "JDOM", nor
|
|
25 may "JDOM" appear in their name, without prior written permission
|
|
26 from the JDOM Project Management <request_AT_jdom_DOT_org>.
|
|
27
|
|
28 In addition, we request (but do not require) that you include in the
|
|
29 end-user documentation provided with the redistribution and/or in the
|
|
30 software itself an acknowledgement equivalent to the following:
|
|
31 "This product includes software developed by the
|
|
32 JDOM Project (http://www.jdom.org/)."
|
|
33 Alternatively, the acknowledgment may be graphical using the logos
|
|
34 available at http://www.jdom.org/images/logos.
|
|
35
|
|
36 THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
|
|
37 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
38 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
39 DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
|
|
40 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
41 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
42 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
|
43 USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
44 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
45 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
|
46 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
47 SUCH DAMAGE.
|
|
48
|
|
49 This software consists of voluntary contributions made by many
|
|
50 individuals on behalf of the JDOM Project and was originally
|
|
51 created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
|
|
52 Brett McLaughlin <brett_AT_jdom_DOT_org>. For more information
|
|
53 on the JDOM Project, please see <http://www.jdom.org/>.
|
|
54
|
|
55 */
|
|
56
|
|
57 package org.jdom;
|
|
58
|
|
59 import java.io.*;
|
|
60
|
|
61 /**
|
|
62 * An XML attribute. Methods allow the user to obtain the value of the attribute
|
|
63 * as well as namespace and type information.
|
|
64 *
|
|
65 * @version $Revision: 1.56 $, $Date: 2007/11/10 05:28:58 $
|
|
66 * @author Brett McLaughlin
|
|
67 * @author Jason Hunter
|
|
68 * @author Elliotte Rusty Harold
|
|
69 * @author Wesley Biggs
|
|
70 * @author Victor Toni
|
|
71 */
|
|
72 public class Attribute implements Serializable, Cloneable {
|
|
73
|
|
74 private static final String CVS_ID =
|
|
75 "@(#) $RCSfile: Attribute.java,v $ $Revision: 1.56 $ $Date: 2007/11/10 05:28:58 $ $Name: jdom_1_1_1 $";
|
|
76
|
|
77 /**
|
|
78 * Attribute type: the attribute has not been declared or type
|
|
79 * is unknown.
|
|
80 *
|
|
81 * @see #getAttributeType
|
|
82 */
|
|
83 public final static int UNDECLARED_TYPE = 0;
|
|
84
|
|
85 /**
|
|
86 * Attribute type: the attribute value is a string.
|
|
87 *
|
|
88 * @see #getAttributeType
|
|
89 */
|
|
90 public final static int CDATA_TYPE = 1;
|
|
91
|
|
92 /**
|
|
93 * Attribute type: the attribute value is a unique identifier.
|
|
94 *
|
|
95 * @see #getAttributeType
|
|
96 */
|
|
97 public final static int ID_TYPE = 2;
|
|
98
|
|
99 /**
|
|
100 * Attribute type: the attribute value is a reference to a
|
|
101 * unique identifier.
|
|
102 *
|
|
103 * @see #getAttributeType
|
|
104 */
|
|
105 public final static int IDREF_TYPE = 3;
|
|
106
|
|
107 /**
|
|
108 * Attribute type: the attribute value is a list of references to
|
|
109 * unique identifiers.
|
|
110 *
|
|
111 * @see #getAttributeType
|
|
112 */
|
|
113 public final static int IDREFS_TYPE = 4;
|
|
114
|
|
115 /**
|
|
116 * Attribute type: the attribute value is the name of an entity.
|
|
117 *
|
|
118 * @see #getAttributeType
|
|
119 */
|
|
120 public final static int ENTITY_TYPE = 5;
|
|
121
|
|
122 /**
|
|
123 * <p>
|
|
124 * Attribute type: the attribute value is a list of entity names.
|
|
125 * </p>
|
|
126 *
|
|
127 * @see #getAttributeType
|
|
128 */
|
|
129 public final static int ENTITIES_TYPE = 6;
|
|
130
|
|
131 /**
|
|
132 * Attribute type: the attribute value is a name token.
|
|
133 * <p>
|
|
134 * According to SAX 2.0 specification, attributes of enumerated
|
|
135 * types should be reported as "NMTOKEN" by SAX parsers. But the
|
|
136 * major parsers (Xerces and Crimson) provide specific values
|
|
137 * that permit to recognize them as {@link #ENUMERATED_TYPE}.
|
|
138 *
|
|
139 * @see #getAttributeType
|
|
140 */
|
|
141 public final static int NMTOKEN_TYPE = 7;
|
|
142
|
|
143 /**
|
|
144 * Attribute type: the attribute value is a list of name tokens.
|
|
145 *
|
|
146 * @see #getAttributeType
|
|
147 */
|
|
148 public final static int NMTOKENS_TYPE = 8;
|
|
149
|
|
150 /**
|
|
151 * Attribute type: the attribute value is the name of a notation.
|
|
152 *
|
|
153 * @see #getAttributeType
|
|
154 */
|
|
155 public final static int NOTATION_TYPE = 9;
|
|
156
|
|
157 /**
|
|
158 * Attribute type: the attribute value is a name token from an
|
|
159 * enumeration.
|
|
160 *
|
|
161 * @see #getAttributeType
|
|
162 */
|
|
163 public final static int ENUMERATED_TYPE = 10;
|
|
164
|
|
165 // Keep the old constant names for one beta cycle to help migration
|
|
166
|
|
167
|
|
168
|
|
169 /** The local name of the <code>Attribute</code> */
|
|
170 protected String name;
|
|
171
|
|
172 /** The <code>{@link Namespace}</code> of the <code>Attribute</code> */
|
|
173 protected transient Namespace namespace;
|
|
174
|
|
175 /** The value of the <code>Attribute</code> */
|
|
176 protected String value;
|
|
177
|
|
178 /** The type of the <code>Attribute</code> */
|
|
179 protected int type = UNDECLARED_TYPE;
|
|
180
|
|
181 /** Parent element, or null if none */
|
|
182 protected Element parent;
|
|
183
|
|
184 /**
|
|
185 * Default, no-args constructor for implementations to use if needed.
|
|
186 */
|
|
187 protected Attribute() {}
|
|
188
|
|
189 /**
|
|
190 * This will create a new <code>Attribute</code> with the
|
|
191 * specified (local) name and value, and in the provided
|
|
192 * <code>{@link Namespace}</code>.
|
|
193 *
|
|
194 * @param name <code>String</code> name of <code>Attribute</code>.
|
|
195 * @param value <code>String</code> value for new attribute.
|
|
196 * @param namespace <code>Namespace</code> namespace for new attribute.
|
|
197 * @throws IllegalNameException if the given name is illegal as an
|
|
198 * attribute name or if if the new namespace is the default
|
|
199 * namespace. Attributes cannot be in a default namespace.
|
|
200 * @throws IllegalDataException if the given attribute value is
|
|
201 * illegal character data (as determined by
|
|
202 * {@link org.jdom.Verifier#checkCharacterData}).
|
|
203 */
|
|
204 public Attribute(final String name, final String value, final Namespace namespace) {
|
|
205 this(name, value, UNDECLARED_TYPE, namespace);
|
|
206 }
|
|
207
|
|
208 /**
|
|
209 * This will create a new <code>Attribute</code> with the
|
|
210 * specified (local) name, value, and type, and in the provided
|
|
211 * <code>{@link Namespace}</code>.
|
|
212 *
|
|
213 * @param name <code>String</code> name of <code>Attribute</code>.
|
|
214 * @param value <code>String</code> value for new attribute.
|
|
215 * @param type <code>int</code> type for new attribute.
|
|
216 * @param namespace <code>Namespace</code> namespace for new attribute.
|
|
217 * @throws IllegalNameException if the given name is illegal as an
|
|
218 * attribute name or if if the new namespace is the default
|
|
219 * namespace. Attributes cannot be in a default namespace.
|
|
220 * @throws IllegalDataException if the given attribute value is
|
|
221 * illegal character data (as determined by
|
|
222 * {@link org.jdom.Verifier#checkCharacterData}) or
|
|
223 * if the given attribute type is not one of the
|
|
224 * supported types.
|
|
225 */
|
|
226 public Attribute(final String name, final String value, final int type, final Namespace namespace) {
|
|
227 setName(name);
|
|
228 setValue(value);
|
|
229 setAttributeType(type);
|
|
230 setNamespace(namespace);
|
|
231 }
|
|
232
|
|
233 /**
|
|
234 * This will create a new <code>Attribute</code> with the
|
|
235 * specified (local) name and value, and does not place
|
|
236 * the attribute in a <code>{@link Namespace}</code>.
|
|
237 * <p>
|
|
238 * <b>Note</b>: This actually explicitly puts the
|
|
239 * <code>Attribute</code> in the "empty" <code>Namespace</code>
|
|
240 * (<code>{@link Namespace#NO_NAMESPACE}</code>).
|
|
241 *
|
|
242 * @param name <code>String</code> name of <code>Attribute</code>.
|
|
243 * @param value <code>String</code> value for new attribute.
|
|
244 * @throws IllegalNameException if the given name is illegal as an
|
|
245 * attribute name.
|
|
246 * @throws IllegalDataException if the given attribute value is
|
|
247 * illegal character data (as determined by
|
|
248 * {@link org.jdom.Verifier#checkCharacterData}).
|
|
249 */
|
|
250 public Attribute(final String name, final String value) {
|
|
251 this(name, value, UNDECLARED_TYPE, Namespace.NO_NAMESPACE);
|
|
252 }
|
|
253
|
|
254 /**
|
|
255 * This will create a new <code>Attribute</code> with the
|
|
256 * specified (local) name, value and type, and does not place
|
|
257 * the attribute in a <code>{@link Namespace}</code>.
|
|
258 * <p>
|
|
259 * <b>Note</b>: This actually explicitly puts the
|
|
260 * <code>Attribute</code> in the "empty" <code>Namespace</code>
|
|
261 * (<code>{@link Namespace#NO_NAMESPACE}</code>).
|
|
262 *
|
|
263 * @param name <code>String</code> name of <code>Attribute</code>.
|
|
264 * @param value <code>String</code> value for new attribute.
|
|
265 * @param type <code>int</code> type for new attribute.
|
|
266 * @throws IllegalNameException if the given name is illegal as an
|
|
267 * attribute name.
|
|
268 * @throws IllegalDataException if the given attribute value is
|
|
269 * illegal character data (as determined by
|
|
270 * {@link org.jdom.Verifier#checkCharacterData}) or
|
|
271 * if the given attribute type is not one of the
|
|
272 * supported types.
|
|
273 */
|
|
274 public Attribute(final String name, final String value, final int type) {
|
|
275 this(name, value, type, Namespace.NO_NAMESPACE);
|
|
276 }
|
|
277
|
|
278 /**
|
|
279 * This will return the parent of this <code>Attribute</code>.
|
|
280 * If there is no parent, then this returns <code>null</code>.
|
|
281 *
|
|
282 * @return parent of this <code>Attribute</code>
|
|
283 */
|
|
284 public Element getParent() {
|
|
285 return parent;
|
|
286 }
|
|
287
|
|
288 /**
|
|
289 * This retrieves the owning <code>{@link Document}</code> for
|
|
290 * this Attribute, or null if not a currently a member of a
|
|
291 * <code>{@link Document}</code>.
|
|
292 *
|
|
293 * @return <code>Document</code> owning this Attribute, or null.
|
|
294 */
|
|
295 public Document getDocument() {
|
|
296 final Element parentElement = getParent();
|
|
297 if (parentElement != null) {
|
|
298 return parentElement.getDocument();
|
|
299 }
|
|
300
|
|
301 return null;
|
|
302 }
|
|
303
|
|
304 /**
|
|
305 * This will set the parent of this <code>Attribute</code>.
|
|
306 *
|
|
307 * @param parent <code>Element</code> to be new parent.
|
|
308 * @return this <code>Attribute</code> modified.
|
|
309 */
|
|
310 protected Attribute setParent(final Element parent) {
|
|
311 this.parent = parent;
|
|
312 return this;
|
|
313 }
|
|
314
|
|
315 /**
|
|
316 * This detaches the <code>Attribute</code> from its parent, or does
|
|
317 * nothing if the <code>Attribute</code> has no parent.
|
|
318 *
|
|
319 * @return <code>Attribute</code> - this <code>Attribute</code> modified.
|
|
320 */
|
|
321 public Attribute detach() {
|
|
322 final Element parentElement = getParent();
|
|
323 if (parentElement != null) {
|
|
324 parentElement.removeAttribute(getName(),getNamespace());
|
|
325 }
|
|
326
|
|
327 return this;
|
|
328 }
|
|
329
|
|
330 /**
|
|
331 * This will retrieve the local name of the
|
|
332 * <code>Attribute</code>. For any XML attribute
|
|
333 * which appears as
|
|
334 * <code>[namespacePrefix]:[attributeName]</code>,
|
|
335 * the local name of the attribute would be
|
|
336 * <code>[attributeName]</code>. When the attribute
|
|
337 * has no namespace, the local name is simply the attribute
|
|
338 * name.
|
|
339 * <p>
|
|
340 * To obtain the namespace prefix for this
|
|
341 * attribute, the
|
|
342 * <code>{@link #getNamespacePrefix()}</code>
|
|
343 * method should be used.
|
|
344 *
|
|
345 * @return <code>String</code> - name of this attribute,
|
|
346 * without any namespace prefix.
|
|
347 */
|
|
348 public String getName() {
|
|
349 return name;
|
|
350 }
|
|
351
|
|
352 /**
|
|
353 * This sets the local name of the <code>Attribute</code>.
|
|
354 *
|
|
355 * @param name the new local name to set
|
|
356 * @return <code>Attribute</code> - the attribute modified.
|
|
357 * @throws IllegalNameException if the given name is illegal as an
|
|
358 * attribute name.
|
|
359 */
|
|
360 public Attribute setName(final String name) {
|
|
361 final String reason = Verifier.checkAttributeName(name);
|
|
362 if (reason != null) {
|
|
363 throw new IllegalNameException(name, "attribute", reason);
|
|
364 }
|
|
365 this.name = name;
|
|
366 return this;
|
|
367 }
|
|
368
|
|
369 /**
|
|
370 * This will retrieve the qualified name of the <code>Attribute</code>.
|
|
371 * For any XML attribute whose name is
|
|
372 * <code>[namespacePrefix]:[elementName]</code>,
|
|
373 * the qualified name of the attribute would be
|
|
374 * everything (both namespace prefix and
|
|
375 * element name). When the attribute has no
|
|
376 * namespace, the qualified name is simply the attribute's
|
|
377 * local name.
|
|
378 * <p>
|
|
379 * To obtain the local name of the attribute, the
|
|
380 * <code>{@link #getName()}</code> method should be used.
|
|
381 * <p>
|
|
382 * To obtain the namespace prefix for this attribute,
|
|
383 * the <code>{@link #getNamespacePrefix()}</code>
|
|
384 * method should be used.
|
|
385 *
|
|
386 * @return <code>String</code> - full name for this element.
|
|
387 */
|
|
388 public String getQualifiedName() {
|
|
389 // Note: Any changes here should be reflected in
|
|
390 // XMLOutputter.printQualifiedName()
|
|
391 final String prefix = namespace.getPrefix();
|
|
392
|
|
393 // no prefix found
|
|
394 if ((prefix == null) || ("".equals(prefix))) {
|
|
395 return getName();
|
|
396 } else {
|
|
397 return new StringBuffer(prefix)
|
|
398 .append(':')
|
|
399 .append(getName())
|
|
400 .toString();
|
|
401 }
|
|
402 }
|
|
403
|
|
404 /**
|
|
405 * This will retrieve the namespace prefix of the
|
|
406 * <code>Attribute</code>. For any XML attribute
|
|
407 * which appears as
|
|
408 * <code>[namespacePrefix]:[attributeName]</code>,
|
|
409 * the namespace prefix of the attribute would be
|
|
410 * <code>[namespacePrefix]</code>. When the attribute
|
|
411 * has no namespace, an empty <code>String</code> is returned.
|
|
412 *
|
|
413 * @return <code>String</code> - namespace prefix of this
|
|
414 * attribute.
|
|
415 */
|
|
416 public String getNamespacePrefix() {
|
|
417 return namespace.getPrefix();
|
|
418 }
|
|
419
|
|
420 /**
|
|
421 * This returns the URI mapped to this <code>Attribute</code>'s
|
|
422 * prefix. If no mapping is found, an empty <code>String</code> is
|
|
423 * returned.
|
|
424 *
|
|
425 * @return <code>String</code> - namespace URI for this <code>Attribute</code>.
|
|
426 */
|
|
427 public String getNamespaceURI() {
|
|
428 return namespace.getURI();
|
|
429 }
|
|
430
|
|
431 /**
|
|
432 * This will return this <code>Attribute</code>'s
|
|
433 * <code>{@link Namespace}</code>.
|
|
434 *
|
|
435 * @return <code>Namespace</code> - Namespace object for this <code>Attribute</code>
|
|
436 */
|
|
437 public Namespace getNamespace() {
|
|
438 return namespace;
|
|
439 }
|
|
440
|
|
441 /**
|
|
442 * This sets this <code>Attribute</code>'s <code>{@link Namespace}</code>.
|
|
443 * If the provided namespace is null, the attribute will have no namespace.
|
|
444 * The namespace must have a prefix.
|
|
445 *
|
|
446 * @param namespace the new namespace
|
|
447 * @return <code>Element</code> - the element modified.
|
|
448 * @throws IllegalNameException if the new namespace is the default
|
|
449 * namespace. Attributes cannot be in a default namespace.
|
|
450 */
|
|
451 public Attribute setNamespace(Namespace namespace) {
|
|
452 if (namespace == null) {
|
|
453 namespace = Namespace.NO_NAMESPACE;
|
|
454 }
|
|
455
|
|
456 // Verify the attribute isn't trying to be in a default namespace
|
|
457 // Attributes can't be in a default namespace
|
|
458 if (namespace != Namespace.NO_NAMESPACE &&
|
|
459 "".equals(namespace.getPrefix())) {
|
|
460 throw new IllegalNameException("", "attribute namespace",
|
|
461 "An attribute namespace without a prefix can only be the " +
|
|
462 "NO_NAMESPACE namespace");
|
|
463 }
|
|
464 this.namespace = namespace;
|
|
465 return this;
|
|
466 }
|
|
467
|
|
468 /**
|
|
469 * This will return the actual textual value of this
|
|
470 * <code>Attribute</code>. This will include all text
|
|
471 * within the quotation marks.
|
|
472 *
|
|
473 * @return <code>String</code> - value for this attribute.
|
|
474 */
|
|
475 public String getValue() {
|
|
476 return value;
|
|
477 }
|
|
478
|
|
479 /**
|
|
480 * This will set the value of the <code>Attribute</code>.
|
|
481 *
|
|
482 * @param value <code>String</code> value for the attribute.
|
|
483 * @return <code>Attribute</code> - this Attribute modified.
|
|
484 * @throws IllegalDataException if the given attribute value is
|
|
485 * illegal character data (as determined by
|
|
486 * {@link org.jdom.Verifier#checkCharacterData}).
|
|
487 */
|
|
488 public Attribute setValue(final String value) {
|
|
489 final String reason = Verifier.checkCharacterData(value);
|
|
490 if (reason != null) {
|
|
491 throw new IllegalDataException(value, "attribute", reason);
|
|
492 }
|
|
493 this.value = value;
|
|
494 return this;
|
|
495 }
|
|
496
|
|
497 /**
|
|
498 * This will return the actual declared type of this
|
|
499 * <code>Attribute</code>.
|
|
500 *
|
|
501 * @return <code>int</code> - type for this attribute.
|
|
502 */
|
|
503 public int getAttributeType() {
|
|
504 return type;
|
|
505 }
|
|
506
|
|
507 /**
|
|
508 * This will set the type of the <code>Attribute</code>.
|
|
509 *
|
|
510 * @param type <code>int</code> type for the attribute.
|
|
511 * @return <code>Attribute</code> - this Attribute modified.
|
|
512 * @throws IllegalDataException if the given attribute type is
|
|
513 * not one of the supported types.
|
|
514 */
|
|
515 public Attribute setAttributeType(final int type) {
|
|
516 if ((type < UNDECLARED_TYPE) || (type > ENUMERATED_TYPE)) {
|
|
517 throw new IllegalDataException(String.valueOf(type),
|
|
518 "attribute", "Illegal attribute type");
|
|
519 }
|
|
520 this.type = type;
|
|
521 return this;
|
|
522 }
|
|
523
|
|
524 /**
|
|
525 * This returns a <code>String</code> representation of the
|
|
526 * <code>Attribute</code>, suitable for debugging.
|
|
527 *
|
|
528 * @return <code>String</code> - information about the
|
|
529 * <code>Attribute</code>
|
|
530 */
|
|
531 public String toString() {
|
|
532 return new StringBuffer()
|
|
533 .append("[Attribute: ")
|
|
534 .append(getQualifiedName())
|
|
535 .append("=\"")
|
|
536 .append(value)
|
|
537 .append("\"")
|
|
538 .append("]")
|
|
539 .toString();
|
|
540 }
|
|
541
|
|
542 /**
|
|
543 * This tests for equality of this <code>Attribute</code> to the supplied
|
|
544 * <code>Object</code>.
|
|
545 *
|
|
546 * @param ob <code>Object</code> to compare to.
|
|
547 * @return <code>boolean</code> - whether the <code>Attribute</code> is
|
|
548 * equal to the supplied <code>Object</code>.
|
|
549 */
|
|
550 public final boolean equals(final Object ob) {
|
|
551 return (ob == this);
|
|
552 }
|
|
553
|
|
554 /**
|
|
555 * This returns the hash code for this <code>Attribute</code>.
|
|
556 *
|
|
557 * @return <code>int</code> - hash code.
|
|
558 */
|
|
559 public final int hashCode() {
|
|
560 return super.hashCode();
|
|
561 }
|
|
562
|
|
563 /**
|
|
564 * This will return a clone of this <code>Attribute</code>.
|
|
565 *
|
|
566 * @return <code>Object</code> - clone of this <code>Attribute</code>.
|
|
567 */
|
|
568 public Object clone() {
|
|
569 Attribute attribute = null;
|
|
570 try {
|
|
571 attribute = (Attribute) super.clone();
|
|
572 }
|
|
573 catch (final CloneNotSupportedException ignore) {
|
|
574 // Won't happen
|
|
575 }
|
|
576
|
|
577 // Name, namespace, and value are references to imutable objects
|
|
578 // and are copied by super.clone() (aka Object.clone())
|
|
579
|
|
580 // super.clone() copies reference to set parent to null
|
|
581 attribute.parent = null;
|
|
582 return attribute;
|
|
583 }
|
|
584
|
|
585 /////////////////////////////////////////////////////////////////
|
|
586 // Convenience Methods below here
|
|
587 /////////////////////////////////////////////////////////////////
|
|
588
|
|
589 /**
|
|
590 * This gets the value of the attribute, in
|
|
591 * <code>int</code> form, and if no conversion
|
|
592 * can occur, throws a
|
|
593 * <code>{@link DataConversionException}</code>
|
|
594 *
|
|
595 * @return <code>int</code> value of attribute.
|
|
596 * @throws DataConversionException when conversion fails.
|
|
597 */
|
|
598 public int getIntValue() throws DataConversionException {
|
|
599 try {
|
|
600 return Integer.parseInt(value.trim());
|
|
601 } catch (final NumberFormatException e) {
|
|
602 throw new DataConversionException(name, "int");
|
|
603 }
|
|
604 }
|
|
605
|
|
606 /**
|
|
607 * This gets the value of the attribute, in
|
|
608 * <code>long</code> form, and if no conversion
|
|
609 * can occur, throws a
|
|
610 * <code>{@link DataConversionException}</code>
|
|
611 *
|
|
612 * @return <code>long</code> value of attribute.
|
|
613 * @throws DataConversionException when conversion fails.
|
|
614 */
|
|
615 public long getLongValue() throws DataConversionException {
|
|
616 try {
|
|
617 return Long.parseLong(value.trim());
|
|
618 } catch (final NumberFormatException e) {
|
|
619 throw new DataConversionException(name, "long");
|
|
620 }
|
|
621 }
|
|
622
|
|
623 /**
|
|
624 * This gets the value of the attribute, in
|
|
625 * <code>float</code> form, and if no conversion
|
|
626 * can occur, throws a
|
|
627 * <code>{@link DataConversionException}</code>
|
|
628 *
|
|
629 * @return <code>float</code> value of attribute.
|
|
630 * @throws DataConversionException when conversion fails.
|
|
631 */
|
|
632 public float getFloatValue() throws DataConversionException {
|
|
633 try {
|
|
634 // Avoid Float.parseFloat() to support JDK 1.1
|
|
635 return Float.valueOf(value.trim()).floatValue();
|
|
636 } catch (final NumberFormatException e) {
|
|
637 throw new DataConversionException(name, "float");
|
|
638 }
|
|
639 }
|
|
640
|
|
641 /**
|
|
642 * This gets the value of the attribute, in
|
|
643 * <code>double</code> form, and if no conversion
|
|
644 * can occur, throws a
|
|
645 * <code>{@link DataConversionException}</code>
|
|
646 *
|
|
647 * @return <code>double</code> value of attribute.
|
|
648 * @throws DataConversionException when conversion fails.
|
|
649 */
|
|
650 public double getDoubleValue() throws DataConversionException {
|
|
651 try {
|
|
652 // Avoid Double.parseDouble() to support JDK 1.1
|
|
653 return Double.valueOf(value.trim()).doubleValue();
|
|
654 } catch (final NumberFormatException e) {
|
|
655 // Specially handle INF and -INF that Double.valueOf doesn't do
|
|
656 String v = value.trim();
|
|
657 if ("INF".equals(v)) {
|
|
658 return Double.POSITIVE_INFINITY;
|
|
659 }
|
|
660 if ("-INF".equals(v)) {
|
|
661 return Double.NEGATIVE_INFINITY;
|
|
662 }
|
|
663 throw new DataConversionException(name, "double");
|
|
664 }
|
|
665 }
|
|
666
|
|
667 /**
|
|
668 * This gets the effective boolean value of the attribute, or throws a
|
|
669 * <code>{@link DataConversionException}</code> if a conversion can't be
|
|
670 * performed. True values are: "true", "on", "1", and "yes". False
|
|
671 * values are: "false", "off", "0", and "no". Values are trimmed before
|
|
672 * comparison. Values other than those listed here throw the exception.
|
|
673 *
|
|
674 * @return <code>boolean</code> value of attribute.
|
|
675 * @throws DataConversionException when conversion fails.
|
|
676 */
|
|
677 public boolean getBooleanValue() throws DataConversionException {
|
|
678 final String valueTrim = value.trim();
|
|
679 if (
|
|
680 (valueTrim.equalsIgnoreCase("true")) ||
|
|
681 (valueTrim.equalsIgnoreCase("on")) ||
|
|
682 (valueTrim.equalsIgnoreCase("1")) ||
|
|
683 (valueTrim.equalsIgnoreCase("yes"))) {
|
|
684 return true;
|
|
685 } else if (
|
|
686 (valueTrim.equalsIgnoreCase("false")) ||
|
|
687 (valueTrim.equalsIgnoreCase("off")) ||
|
|
688 (valueTrim.equalsIgnoreCase("0")) ||
|
|
689 (valueTrim.equalsIgnoreCase("no"))
|
|
690 ) {
|
|
691 return false;
|
|
692 } else {
|
|
693 throw new DataConversionException(name, "boolean");
|
|
694 }
|
|
695 }
|
|
696
|
|
697 // Support a custom Namespace serialization so no two namespace
|
|
698 // object instances may exist for the same prefix/uri pair
|
|
699 private void writeObject(final ObjectOutputStream out) throws IOException {
|
|
700
|
|
701 out.defaultWriteObject();
|
|
702
|
|
703 // We use writeObject() and not writeUTF() to minimize space
|
|
704 // This allows for writing pointers to already written strings
|
|
705 out.writeObject(namespace.getPrefix());
|
|
706 out.writeObject(namespace.getURI());
|
|
707 }
|
|
708
|
|
709 private void readObject(final ObjectInputStream in)
|
|
710 throws IOException, ClassNotFoundException {
|
|
711
|
|
712 in.defaultReadObject();
|
|
713
|
|
714 namespace = Namespace.getNamespace(
|
|
715 (String) in.readObject(), (String) in.readObject());
|
|
716 }
|
|
717 }
|