KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > xquark > xpath > datamodel > xerces > dom > ElementImpl


1 /*
2  * The Apache Software License, Version 1.1
3  *
4  *
5  * Copyright (c) 1999 The Apache Software Foundation. All rights
6  * 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 following disclaimer in
17  * the documentation and/or other materials provided with the
18  * distribution.
19  *
20  * 3. The end-user documentation included with the redistribution,
21  * if any, must include the following acknowledgment:
22  * "This product includes software developed by the
23  * Apache Software Foundation (http://www.apache.org/)."
24  * Alternately, this acknowledgment may appear in the software itself,
25  * if and wherever such third-party acknowledgments normally appear.
26  *
27  * 4. The names "Xerces" and "Apache Software Foundation" must
28  * not be used to endorse or promote products derived from this
29  * software without prior written permission. For written
30  * permission, please contact apache@apache.org.
31  *
32  * 5. Products derived from this software may not be called "Apache",
33  * nor may "Apache" appear in their name, without prior written
34  * permission of the Apache Software Foundation.
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 APACHE SOFTWARE FOUNDATION OR
40  * ITS 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  *
50  * This software consists of voluntary contributions made by many
51  * individuals on behalf of the Apache Software Foundation and was
52  * originally based on software copyright (c) 1999, International
53  * Business Machines, Inc., http://www.apache.org. For more
54  * information on the Apache Software Foundation, please see
55  * <http://www.apache.org/>.
56  */

57
58 package org.xquark.xpath.datamodel.xerces.dom;
59
60 import org.w3c.dom.*;
61
62 /**
63  * Elements represent most of the "markup" and structure of the
64  * document. They contain both the data for the element itself
65  * (element name and attributes), and any contained nodes, including
66  * document text (as children).
67  * <P>
68  * Elements may have Attributes associated with them; the API for this is
69  * defined in Node, but the function is implemented here. In general, XML
70  * applications should retrive Attributes as Nodes, since they may contain
71  * entity references and hence be a fairly complex sub-tree. HTML users will
72  * be dealing with simple string values, and convenience methods are provided
73  * to work in terms of Strings.
74  * <P>
75  * ElementImpl does not support Namespaces. ElementNSImpl, which inherits from
76  * it, does.
77  * @see ElementNSImpl
78  *
79  * @author Arnaud Le Hors, IBM
80  * @author Joe Kesselman, IBM
81  * @author Andy Clark, IBM
82  * @author Ralf Pfeiffer, IBM
83  * @version
84  * @since PR-DOM-Level-1-19980818.
85  */

86 public class ElementImpl
87     extends ParentNode
88     implements Element {
89
90     //
91
// Constants
92
//
93

94     /** Serialization version. */
95     static final long serialVersionUID = 3717253516652722278L;
96     //
97
// Data
98
//
99

100     /** Element name. */
101     protected String JavaDoc name;
102
103     /** Attributes. */
104     protected AttributeMap attributes;
105
106     //
107
// Constructors
108
//
109

110     /** Factory constructor. */
111     public ElementImpl(DocumentImpl ownerDoc, String JavaDoc name) {
112         super(ownerDoc);
113         this.name = name;
114         needsSyncData(true); // synchronizeData will initialize attributes
115
}
116
117     // for ElementNSImpl
118
protected ElementImpl() {}
119     
120     //
121
// Node methods
122
//
123

124     
125     /**
126      * A short integer indicating what type of node this is. The named
127      * constants for this value are defined in the org.w3c.dom.Node interface.
128      */

129     public short getNodeType() {
130         return Node.ELEMENT_NODE;
131     }
132
133     /**
134      * Returns the element name
135      */

136     public String JavaDoc getNodeName() {
137         if (needsSyncData()) {
138             synchronizeData();
139         }
140         return name;
141     }
142
143     /**
144      * Retrieve all the Attributes as a set. Note that this API is inherited
145      * from Node rather than specified on Element; in fact only Elements will
146      * ever have Attributes, but they want to allow folks to "blindly" operate
147      * on the tree as a set of Nodes.
148      */

149     public NamedNodeMap getAttributes() {
150
151         if (needsSyncData()) {
152             synchronizeData();
153         }
154         if (attributes == null) {
155             attributes = new AttributeMap(this, null);
156         }
157         return attributes;
158
159     } // getAttributes():NamedNodeMap
160

161     /**
162      * Return a duplicate copy of this Element. Note that its children
163      * will not be copied unless the "deep" flag is true, but Attributes
164      * are <i>always</i> replicated.
165      *
166      * @see org.w3c.dom.Node#cloneNode(boolean)
167      */

168     public Node cloneNode(boolean deep) {
169
170         ElementImpl newnode = (ElementImpl) super.cloneNode(deep);
171         // Replicate NamedNodeMap rather than sharing it.
172
if (attributes != null) {
173             newnode.attributes = (AttributeMap) attributes.cloneMap(newnode);
174         }
175         return newnode;
176
177     } // cloneNode(boolean):Node
178

179
180     /**
181      * NON-DOM
182      * set the ownerDocument of this node, its children, and its attributes
183      */

184     void setOwnerDocument(DocumentImpl doc) {
185     super.setOwnerDocument(doc);
186         if (attributes != null) {
187             attributes.setOwnerDocument(doc);
188         }
189     }
190
191     //
192
// Element methods
193
//
194

195     /**
196      * Look up a single Attribute by name. Returns the Attribute's
197      * string value, or an empty string (NOT null!) to indicate that the
198      * name did not map to a currently defined attribute.
199      * <p>
200      * Note: Attributes may contain complex node trees. This method
201      * returns the "flattened" string obtained from Attribute.getValue().
202      * If you need the structure information, see getAttributeNode().
203      */

204     public String JavaDoc getAttribute(String JavaDoc name) {
205
206         if (needsSyncData()) {
207             synchronizeData();
208         }
209         if (attributes == null) {
210             return "";
211         }
212         Attr attr = (Attr)(attributes.getNamedItem(name));
213         return (attr == null) ? "" : attr.getValue();
214
215     } // getAttribute(String):String
216

217
218     /**
219      * Look up a single Attribute by name. Returns the Attribute Node,
220      * so its complete child tree is available. This could be important in
221      * XML, where the string rendering may not be sufficient information.
222      * <p>
223      * If no matching attribute is available, returns null.
224      */

225     public Attr getAttributeNode(String JavaDoc name) {
226
227         if (needsSyncData()) {
228             synchronizeData();
229         }
230         if (attributes == null) {
231             return null;
232         }
233         return (Attr)attributes.getNamedItem(name);
234
235     } // getAttributeNode(String):Attr
236

237
238     /**
239      * Returns a NodeList of all descendent nodes (children,
240      * grandchildren, and so on) which are Elements and which have the
241      * specified tag name.
242      * <p>
243      * Note: NodeList is a "live" view of the DOM. Its contents will
244      * change as the DOM changes, and alterations made to the NodeList
245      * will be reflected in the DOM.
246      *
247      * @param tagname The type of element to gather. To obtain a list of
248      * all elements no matter what their names, use the wild-card tag
249      * name "*".
250      *
251      * @see DeepNodeListImpl
252      */

253     public NodeList getElementsByTagName(String JavaDoc tagname) {
254         return new DeepNodeListImpl(this,tagname);
255     }
256
257     /**
258      * Returns the name of the Element. Note that Element.nodeName() is
259      * defined to also return the tag name.
260      * <p>
261      * This is case-preserving in XML. HTML should uppercasify it on the
262      * way in.
263      */

264     public String JavaDoc getTagName() {
265         if (needsSyncData()) {
266             synchronizeData();
267         }
268         return name;
269     }
270
271     /**
272      * In "normal form" (as read from a source file), there will never be two
273      * Text children in succession. But DOM users may create successive Text
274      * nodes in the course of manipulating the document. Normalize walks the
275      * sub-tree and merges adjacent Texts, as if the DOM had been written out
276      * and read back in again. This simplifies implementation of higher-level
277      * functions that may want to assume that the document is in standard form.
278      * <p>
279      * To normalize a Document, normalize its top-level Element child.
280      * <p>
281      * As of PR-DOM-Level-1-19980818, CDATA -- despite being a subclass of
282      * Text -- is considered "markup" and will _not_ be merged either with
283      * normal Text or with other CDATASections.
284      */

285     public void normalize() {
286         // No need to normalize if already normalized.
287
if (isNormalized()) {
288             return;
289         }
290         if (needsSyncChildren()) {
291             synchronizeChildren();
292         }
293         ChildNode kid, next;
294         for (kid = firstChild; kid != null; kid = next) {
295             next = kid.nextSibling;
296
297             // If kid is a text node, we need to check for one of two
298
// conditions:
299
// 1) There is an adjacent text node
300
// 2) There is no adjacent text node, but kid is
301
// an empty text node.
302
if ( kid.getNodeType() == Node.TEXT_NODE )
303             {
304                 // If an adjacent text node, merge it with kid
305
if ( next!=null && next.getNodeType() == Node.TEXT_NODE )
306                 {
307                     ((Text)kid).appendData(next.getNodeValue());
308                     removeChild( next );
309                     next = kid; // Don't advance; there might be another.
310
}
311                 else
312                 {
313                     // If kid is empty, remove it
314
if ( kid.getNodeValue().length()==0 )
315                         removeChild( kid );
316                 }
317             }
318
319             // Otherwise it might be an Element, which is handled recursively
320
else if (kid.getNodeType() == Node.ELEMENT_NODE) {
321                 kid.normalize();
322             }
323         }
324
325         // We must also normalize all of the attributes
326
if ( attributes!=null )
327         {
328             for( int i=0; i<attributes.getLength(); ++i )
329             {
330                 Node attr = attributes.item(i);
331                 attr.normalize();
332             }
333         }
334
335         // changed() will have occurred when the removeChild() was done,
336
// so does not have to be reissued.
337

338         isNormalized(true);
339     } // normalize()
340

341     /**
342      * Remove the named attribute from this Element. If the removed
343      * Attribute has a default value, it is immediately replaced thereby.
344      * <P>
345      * The default logic is actually implemented in NamedNodeMapImpl.
346      * PR-DOM-Level-1-19980818 doesn't fully address the DTD, so some
347      * of this behavior is likely to change in future versions. ?????
348      * <P>
349      * Note that this call "succeeds" even if no attribute by this name
350      * existed -- unlike removeAttributeNode, which will throw a not-found
351      * exception in that case.
352      *
353      * @throws DOMException(NO_MODIFICATION_ALLOWED_ERR) if the node is
354      * readonly.
355      */

356     public void removeAttribute(String JavaDoc name) {
357
358         if (ownerDocument.errorChecking && isReadOnly()) {
359             throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR,
360                                    "DOM001 Modification not allowed");
361         }
362             
363         if (needsSyncData()) {
364             synchronizeData();
365         }
366
367         if (attributes == null) {
368             return;
369         }
370
371         attributes.safeRemoveNamedItem(name);
372
373     } // removeAttribute(String)
374

375   
376     /**
377      * Remove the specified attribute/value pair. If the removed
378      * Attribute has a default value, it is immediately replaced.
379      * <p>
380      * NOTE: Specifically removes THIS NODE -- not the node with this
381      * name, nor the node with these contents. If the specific Attribute
382      * object passed in is not stored in this Element, we throw a
383      * DOMException. If you really want to remove an attribute by name,
384      * use removeAttribute().
385      *
386      * @return the Attribute object that was removed.
387      * @throws DOMException(NOT_FOUND_ERR) if oldattr is not an attribute of
388      * this Element.
389      * @throws DOMException(NO_MODIFICATION_ALLOWED_ERR) if the node is
390      * readonly.
391      */

392     public Attr removeAttributeNode(Attr oldAttr)
393         throws DOMException {
394
395         if (ownerDocument.errorChecking && isReadOnly()) {
396             throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR,
397                                    "DOM001 Modification not allowed");
398         }
399             
400         if (needsSyncData()) {
401             synchronizeData();
402         }
403
404         if (attributes == null) {
405             throw new DOMException(DOMException.NOT_FOUND_ERR,
406                                        "DOM008 Not found");
407         }
408         return (Attr) attributes.removeNamedItem(oldAttr.getName());
409
410     } // removeAttributeNode(Attr):Attr
411

412    
413     /**
414      * Add a new name/value pair, or replace the value of the existing
415      * attribute having that name.
416      *
417      * Note: this method supports only the simplest kind of Attribute,
418      * one whose value is a string contained in a single Text node.
419      * If you want to assert a more complex value (which XML permits,
420      * though HTML doesn't), see setAttributeNode().
421      *
422      * The attribute is created with specified=true, meaning it's an
423      * explicit value rather than inherited from the DTD as a default.
424      * Again, setAttributeNode can be used to achieve other results.
425      *
426      * @throws DOMException(INVALID_NAME_ERR) if the name is not acceptable.
427      * (Attribute factory will do that test for us.)
428      *
429      * @throws DOMException(NO_MODIFICATION_ALLOWED_ERR) if the node is
430      * readonly.
431      */

432     public void setAttribute(String JavaDoc name, String JavaDoc value) {
433
434         if (ownerDocument.errorChecking && isReadOnly()) {
435             throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR,
436                                    "DOM001 Modification not allowed");
437         }
438
439         if (needsSyncData()) {
440             synchronizeData();
441         }
442
443         Attr newAttr = getAttributeNode(name);
444         if (newAttr == null) {
445             newAttr = getOwnerDocument().createAttribute(name);
446
447             if (attributes == null) {
448                 attributes = new AttributeMap(this, null);
449             }
450
451         newAttr.setNodeValue(value);
452             attributes.setNamedItem(newAttr);
453         }
454     else {
455         newAttr.setNodeValue(value);
456     }
457
458     } // setAttribute(String,String)
459

460     /**
461      * Add a new attribute/value pair, or replace the value of the
462      * existing attribute with that name.
463      * <P>
464      * This method allows you to add an Attribute that has already been
465      * constructed, and hence avoids the limitations of the simple
466      * setAttribute() call. It can handle attribute values that have
467      * arbitrarily complex tree structure -- in particular, those which
468      * had entity references mixed into their text.
469      *
470      * @throws DOMException(INUSE_ATTRIBUTE_ERR) if the Attribute object
471      * has already been assigned to another Element.
472      */

473     public Attr setAttributeNode(Attr newAttr)
474         throws DOMException
475         {
476
477         if (needsSyncData()) {
478             synchronizeData();
479         }
480
481         if (ownerDocument.errorChecking) {
482             if (isReadOnly()) {
483                 throw new DOMException(
484                                      DOMException.NO_MODIFICATION_ALLOWED_ERR,
485                                      "DOM001 Modification not allowed");
486             }
487         
488             if (newAttr.getOwnerDocument() != ownerDocument) {
489             throw new DOMException(DOMException.WRONG_DOCUMENT_ERR,
490                                        "DOM005 Wrong document");
491             }
492         }
493
494         if (attributes == null) {
495             attributes = new AttributeMap(this, null);
496         }
497         // This will throw INUSE if necessary
498
return (Attr) attributes.setNamedItem(newAttr);
499
500     } // setAttributeNode(Attr):Attr
501

502     //
503
// DOM2: Namespace methods
504
//
505

506     /**
507      * Introduced in DOM Level 2. <p>
508      *
509      * Retrieves an attribute value by local name and namespace URI.
510      *
511      * @param namespaceURI
512      * The namespace URI of the attribute to
513      * retrieve.
514      * @param localName The local name of the attribute to retrieve.
515      * @return String The Attr value as a string, or empty string
516      * if that attribute
517      * does not have a specified or default value.
518      * @since WD-DOM-Level-2-19990923
519      */

520     public String JavaDoc getAttributeNS(String JavaDoc namespaceURI, String JavaDoc localName) {
521
522         if (needsSyncData()) {
523             synchronizeData();
524         }
525
526         if (attributes == null) {
527             return "";
528         }
529
530         Attr attr = (Attr)(attributes.getNamedItemNS(namespaceURI, localName));
531         return (attr == null) ? "" : attr.getValue();
532
533     } // getAttributeNS(String,String):String
534

535     /**
536      * Introduced in DOM Level 2. <p>
537      *
538      * Adds a new attribute.
539      * If the given namespaceURI is null or an empty string and
540      * the qualifiedName has a prefix that is "xml", the new attribute is bound to the
541      * predefined namespace "http://www.w3.org/XML/1998/namespace" [Namespaces].
542      * If an attribute with the same local name and namespace URI is already present on
543      * the element, its prefix is changed to be the prefix part of the qualifiedName, and
544      * its value is changed to be the value parameter. This value is a simple string, it is not
545      * parsed as it is being set. So any markup (such as syntax to be recognized as an
546      * entity reference) is treated as literal text, and needs to be appropriately escaped by
547      * the implementation when it is written out. In order to assign an attribute value that
548      * contains entity references, the user must create an Attr node plus any Text and
549      * EntityReference nodes, build the appropriate subtree, and use
550      * setAttributeNodeNS or setAttributeNode to assign it as the value of an
551      * attribute.
552      * @param namespaceURI
553      * The namespace URI of the attribute to create
554      * or alter.
555      * @param localName The local name of the attribute to create or
556      * alter.
557      * @param value The value to set in string form.
558      * @throws INVALID_CHARACTER_ERR: Raised if the specified
559      * name contains an invalid character.
560      *
561      * @throws NO_MODIFICATION_ALLOWED_ERR: Raised if this
562      * node is readonly.
563      *
564      * @throws NAMESPACE_ERR: Raised if the qualifiedName
565      * has a prefix that is "xml" and the namespaceURI is
566      * neither null nor an empty string nor
567      * "http://www.w3.org/XML/1998/namespace", or if the
568      * qualifiedName has a prefix that is "xmlns" but the
569      * namespaceURI is neither null nor an empty string, or
570      * if if the qualifiedName has a prefix different from
571      * "xml" and "xmlns" and the namespaceURI is null or an
572      * empty string.
573      * @since WD-DOM-Level-2-19990923
574      */

575     public void setAttributeNS(String JavaDoc namespaceURI, String JavaDoc localName, String JavaDoc value) {
576
577         if (ownerDocument.errorChecking && isReadOnly()) {
578             throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR,
579                                    "DOM001 Modification not allowed");
580         }
581
582         if (needsSyncData()) {
583             synchronizeData();
584         }
585
586         Attr newAttr = getAttributeNodeNS(namespaceURI, localName);
587         if (newAttr == null) {
588             newAttr =
589                 getOwnerDocument().createAttributeNS(namespaceURI, localName);
590
591             if (attributes == null) {
592                 attributes = new AttributeMap(this, null);
593             }
594         newAttr.setNodeValue(value);
595             attributes.setNamedItemNS(newAttr);
596         }
597     else {
598         newAttr.setNodeValue(value);
599     }
600
601     } // setAttributeNS(String,String,String)
602

603     /**
604      * Introduced in DOM Level 2. <p>
605      *
606      * Removes an attribute by local name and namespace URI. If the removed
607      * attribute has a default value it is immediately replaced.
608      * The replacing attribute has the same namespace URI and local name,
609      * as well as the original prefix.<p>
610      *
611      * @param namespaceURI The namespace URI of the attribute to remove.
612      *
613      * @param localName The local name of the attribute to remove.
614      * @throws NO_MODIFICATION_ALLOWED_ERR: Raised if this
615      * node is readonly.
616      * @since WD-DOM-Level-2-19990923
617      */

618     public void removeAttributeNS(String JavaDoc namespaceURI, String JavaDoc localName) {
619
620         if (ownerDocument.errorChecking && isReadOnly()) {
621             throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR,
622                                    "DOM001 Modification not allowed");
623         }
624             
625         if (needsSyncData()) {
626             synchronizeData();
627         }
628
629         if (attributes == null) {
630             return;
631         }
632
633         attributes.safeRemoveNamedItemNS(namespaceURI, localName);
634
635     } // removeAttributeNS(String,String)
636

637     /**
638      * Retrieves an Attr node by local name and namespace URI.
639      *
640      * @param namespaceURI The namespace URI of the attribute to
641      * retrieve.
642      * @param localName The local name of the attribute to retrieve.
643      * @return Attr The Attr node with the specified attribute
644      * local name and namespace
645      * URI or null if there is no such attribute.
646      * @since WD-DOM-Level-2-19990923
647      */

648     public Attr getAttributeNodeNS(String JavaDoc namespaceURI, String JavaDoc localName){
649
650         if (needsSyncData()) {
651             synchronizeData();
652         }
653         if (attributes == null) {
654             return null;
655         }
656         return (Attr)attributes.getNamedItemNS(namespaceURI, localName);
657
658     } // getAttributeNodeNS(String,String):Attr
659

660     /**
661      * Introduced in DOM Level 2. <p>
662      *
663      * Adds a new attribute. If an attribute with that local name and
664      * namespace URI is already present in the element, it is replaced
665      * by the new one.
666      *
667      * @param Attr The Attr node to add to the attribute list. When
668      * the Node has no namespaceURI, this method behaves
669      * like setAttributeNode.
670      * @return Attr If the newAttr attribute replaces an existing attribute with the same
671      * local name and namespace URI, the previously existing Attr node is
672      * returned, otherwise null is returned.
673      * @throws WRONG_DOCUMENT_ERR: Raised if newAttr
674      * was created from a different document than the one that
675      * created the element.
676      *
677      * @throws NO_MODIFICATION_ALLOWED_ERR: Raised if
678      * this node is readonly.
679      *
680      * @throws INUSE_ATTRIBUTE_ERR: Raised if newAttr is
681      * already an attribute of another Element object. The
682      * DOM user must explicitly clone Attr nodes to re-use
683      * them in other elements.
684      * @since WD-DOM-Level-2-19990923
685      */

686     public Attr setAttributeNodeNS(Attr newAttr)
687         throws DOMException
688         {
689
690         if (needsSyncData()) {
691             synchronizeData();
692         }
693         if (ownerDocument.errorChecking) {
694             if (isReadOnly()) {
695             throw new DOMException(
696                                      DOMException.NO_MODIFICATION_ALLOWED_ERR,
697                                      "DOM001 Modification not allowed");
698             }
699             if (newAttr.getOwnerDocument() != ownerDocument) {
700                 throw new DOMException(DOMException.WRONG_DOCUMENT_ERR,
701                                        "DOM005 Wrong document");
702             }
703         }
704
705         if (attributes == null) {
706             attributes = new AttributeMap(this, null);
707         }
708         // This will throw INUSE if necessary
709
return (Attr) attributes.setNamedItemNS(newAttr);
710
711     } // setAttributeNodeNS(Attr):Attr
712

713     /**
714      * Introduced in DOM Level 2.
715      */

716     public boolean hasAttributes() {
717         if (needsSyncData()) {
718             synchronizeData();
719         }
720         return (attributes != null && attributes.getLength() != 0);
721     }
722
723     /**
724      * Introduced in DOM Level 2.
725      */

726     public boolean hasAttribute(String JavaDoc name) {
727         return getAttributeNode(name) != null;
728     }
729
730     /**
731      * Introduced in DOM Level 2.
732      */

733     public boolean hasAttributeNS(String JavaDoc namespaceURI, String JavaDoc localName) {
734         return getAttributeNodeNS(namespaceURI, localName) != null;
735     }
736
737     /**
738      * Introduced in DOM Level 2. <p>
739      *
740      * Returns a NodeList of all the Elements with a given local name and
741      * namespace URI in the order in which they would be encountered in a preorder
742      * traversal of the Document tree, starting from this node.
743      *
744      * @param namespaceURI The namespace URI of the elements to match
745      * on. The special value "*" matches all
746      * namespaces. When it is null or an empty
747      * string, this method behaves like
748      * getElementsByTagName.
749      * @param localName The local name of the elements to match on.
750      * The special value "*" matches all local names.
751      * @return NodeList A new NodeList object containing all the matched Elements.
752      * @since WD-DOM-Level-2-19990923
753      */

754     public NodeList getElementsByTagNameNS(String JavaDoc namespaceURI, String JavaDoc localName) {
755         return new DeepNodeListImpl(this, namespaceURI, localName);
756     }
757
758     //
759
// Public methods
760
//
761

762     /**
763      * NON-DOM: Subclassed to flip the attributes' readonly switch as well.
764      * @see NodeImpl#setReadOnly
765      */

766     public void setReadOnly(boolean readOnly, boolean deep) {
767         super.setReadOnly(readOnly,deep);
768         if (attributes != null) {
769             attributes.setReadOnly(readOnly,true);
770         }
771     }
772
773     //
774
// Protected methods
775
//
776

777     /** Synchronizes the data (name and value) for fast nodes. */
778     protected void synchronizeData() {
779
780         // no need to sync in the future
781
needsSyncData(false);
782
783         // we don't want to generate any event for this so turn them off
784
boolean orig = ownerDocument.mutationEvents;
785         ownerDocument.mutationEvents = false;
786
787         // attributes
788
setupDefaultAttributes();
789
790         // set mutation events flag back to its original value
791
ownerDocument.mutationEvents = orig;
792
793     } // synchronizeData()
794

795     /** Setup the default attributes. */
796     protected void setupDefaultAttributes() {
797         NamedNodeMapImpl defaults = getDefaultAttributes();
798         if (defaults != null) {
799             attributes = new AttributeMap(this, defaults);
800         }
801     }
802
803     /** Reconcile default attributes. */
804     protected void reconcileDefaultAttributes() {
805         NamedNodeMapImpl defaults = getDefaultAttributes();
806         if (defaults != null) {
807             attributes.reconcileDefaults(defaults);
808         }
809     }
810
811     /** Get the default attributes. */
812     protected NamedNodeMapImpl getDefaultAttributes() {
813
814         DocumentTypeImpl doctype =
815             (DocumentTypeImpl) ownerDocument.getDoctype();
816         if (doctype == null) {
817             return null;
818         }
819         ElementDefinitionImpl eldef =
820             (ElementDefinitionImpl)doctype.getElements()
821                                                .getNamedItem(getNodeName());
822         if (eldef == null) {
823             return null;
824         }
825         return (NamedNodeMapImpl) eldef.getAttributes();
826
827     } // setupAttributes(DocumentImpl)
828

829 } // class ElementImpl
830
Popular Tags