KickJava   Java API By Example, From Geeks To Geeks.

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

93 public class ElementImpl
94     extends ParentNode
95     implements Element JavaDoc {
96
97     //
98
// Constants
99
//
100

101     /** Serialization version. */
102     static final long serialVersionUID = 3717253516652722278L;
103     //
104
// Data
105
//
106

107     /** Element name. */
108     protected String JavaDoc name;
109
110     /** Attributes. */
111     protected AttributeMap attributes;
112
113     //
114
// Constructors
115
//
116

117     /** Factory constructor. */
118     public ElementImpl(CoreDocumentImpl ownerDoc, String JavaDoc name) {
119         super(ownerDoc);
120         this.name = name;
121         needsSyncData(true); // synchronizeData will initialize attributes
122
}
123
124     // for ElementNSImpl
125
protected ElementImpl() {}
126     
127     //
128
// Node methods
129
//
130

131     
132     /**
133      * A short integer indicating what type of node this is. The named
134      * constants for this value are defined in the org.w3c.dom.Node interface.
135      */

136     public short getNodeType() {
137         return Node.ELEMENT_NODE;
138     }
139
140     /**
141      * Returns the element name
142      */

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

156     public NamedNodeMap JavaDoc getAttributes() {
157
158         if (needsSyncData()) {
159             synchronizeData();
160         }
161         if (attributes == null) {
162             attributes = new AttributeMap(this, null);
163         }
164         return attributes;
165
166     } // getAttributes():NamedNodeMap
167

168     /**
169      * Return a duplicate copy of this Element. Note that its children
170      * will not be copied unless the "deep" flag is true, but Attributes
171      * are <i>always</i> replicated.
172      *
173      * @see org.w3c.dom.Node#cloneNode(boolean)
174      */

175     public Node JavaDoc cloneNode(boolean deep) {
176
177         ElementImpl newnode = (ElementImpl) super.cloneNode(deep);
178         // Replicate NamedNodeMap rather than sharing it.
179
if (attributes != null) {
180             newnode.attributes = (AttributeMap) attributes.cloneMap(newnode);
181         }
182         return newnode;
183
184     } // cloneNode(boolean):Node
185

186
187     /**
188      * NON-DOM
189      * set the ownerDocument of this node, its children, and its attributes
190      */

191     void setOwnerDocument(CoreDocumentImpl doc) {
192     super.setOwnerDocument(doc);
193         if (attributes != null) {
194             attributes.setOwnerDocument(doc);
195         }
196     }
197
198     //
199
// Element methods
200
//
201

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

211     public String JavaDoc getAttribute(String JavaDoc name) {
212
213         if (needsSyncData()) {
214             synchronizeData();
215         }
216         if (attributes == null) {
217             return "";
218         }
219         Attr JavaDoc attr = (Attr JavaDoc)(attributes.getNamedItem(name));
220         return (attr == null) ? "" : attr.getValue();
221
222     } // getAttribute(String):String
223

224
225     /**
226      * Look up a single Attribute by name. Returns the Attribute Node,
227      * so its complete child tree is available. This could be important in
228      * XML, where the string rendering may not be sufficient information.
229      * <p>
230      * If no matching attribute is available, returns null.
231      */

232     public Attr JavaDoc getAttributeNode(String JavaDoc name) {
233
234         if (needsSyncData()) {
235             synchronizeData();
236         }
237         if (attributes == null) {
238             return null;
239         }
240         return (Attr JavaDoc)attributes.getNamedItem(name);
241
242     } // getAttributeNode(String):Attr
243

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

260     public NodeList JavaDoc getElementsByTagName(String JavaDoc tagname) {
261         return new DeepNodeListImpl(this,tagname);
262     }
263
264     /**
265      * Returns the name of the Element. Note that Element.nodeName() is
266      * defined to also return the tag name.
267      * <p>
268      * This is case-preserving in XML. HTML should uppercasify it on the
269      * way in.
270      */

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

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

345         isNormalized(true);
346     } // normalize()
347

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

363     public void removeAttribute(String JavaDoc name) {
364
365         if (ownerDocument.errorChecking && isReadOnly()) {
366             throw new DOMException JavaDoc(DOMException.NO_MODIFICATION_ALLOWED_ERR,
367                                    "DOM001 Modification not allowed");
368         }
369             
370         if (needsSyncData()) {
371             synchronizeData();
372         }
373
374         if (attributes == null) {
375             return;
376         }
377
378         attributes.safeRemoveNamedItem(name);
379
380     } // removeAttribute(String)
381

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

399     public Attr JavaDoc removeAttributeNode(Attr JavaDoc oldAttr)
400         throws DOMException JavaDoc {
401
402         if (ownerDocument.errorChecking && isReadOnly()) {
403             throw new DOMException JavaDoc(DOMException.NO_MODIFICATION_ALLOWED_ERR,
404                                    "DOM001 Modification not allowed");
405         }
406             
407         if (needsSyncData()) {
408             synchronizeData();
409         }
410
411         if (attributes == null) {
412             throw new DOMException JavaDoc(DOMException.NOT_FOUND_ERR,
413                                        "DOM008 Not found");
414         }
415         return (Attr JavaDoc) attributes.removeNamedItem(oldAttr.getName());
416
417     } // removeAttributeNode(Attr):Attr
418

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

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

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

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

509     //
510
// DOM2: Namespace methods
511
//
512

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

527     public String JavaDoc getAttributeNS(String JavaDoc namespaceURI, String JavaDoc localName) {
528
529         if (needsSyncData()) {
530             synchronizeData();
531         }
532
533         if (attributes == null) {
534             return "";
535         }
536
537         Attr JavaDoc attr = (Attr JavaDoc)(attributes.getNamedItemNS(namespaceURI, localName));
538         return (attr == null) ? "" : attr.getValue();
539
540     } // getAttributeNS(String,String):String
541

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

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

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

626     public void removeAttributeNS(String JavaDoc namespaceURI, String JavaDoc localName) {
627
628         if (ownerDocument.errorChecking && isReadOnly()) {
629             throw new DOMException JavaDoc(DOMException.NO_MODIFICATION_ALLOWED_ERR,
630                                    "DOM001 Modification not allowed");
631         }
632             
633         if (needsSyncData()) {
634             synchronizeData();
635         }
636
637         if (attributes == null) {
638             return;
639         }
640
641         attributes.safeRemoveNamedItemNS(namespaceURI, localName);
642
643     } // removeAttributeNS(String,String)
644

645     /**
646      * Retrieves an Attr node by local name and namespace URI.
647      *
648      * @param namespaceURI The namespace URI of the attribute to
649      * retrieve.
650      * @param localName The local name of the attribute to retrieve.
651      * @return Attr The Attr node with the specified attribute
652      * local name and namespace
653      * URI or null if there is no such attribute.
654      * @since WD-DOM-Level-2-19990923
655      */

656     public Attr JavaDoc getAttributeNodeNS(String JavaDoc namespaceURI, String JavaDoc localName){
657
658         if (needsSyncData()) {
659             synchronizeData();
660         }
661         if (attributes == null) {
662             return null;
663         }
664         return (Attr JavaDoc)attributes.getNamedItemNS(namespaceURI, localName);
665
666     } // getAttributeNodeNS(String,String):Attr
667

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

695     public Attr JavaDoc setAttributeNodeNS(Attr JavaDoc newAttr)
696         throws DOMException JavaDoc
697         {
698
699         if (needsSyncData()) {
700             synchronizeData();
701         }
702         if (ownerDocument.errorChecking) {
703             if (isReadOnly()) {
704             throw new DOMException JavaDoc(
705                                      DOMException.NO_MODIFICATION_ALLOWED_ERR,
706                                      "DOM001 Modification not allowed");
707             }
708             if (newAttr.getOwnerDocument() != ownerDocument) {
709                 throw new DOMException JavaDoc(DOMException.WRONG_DOCUMENT_ERR,
710                                        "DOM005 Wrong document");
711             }
712         }
713
714         if (attributes == null) {
715             attributes = new AttributeMap(this, null);
716         }
717         // This will throw INUSE if necessary
718
return (Attr JavaDoc) attributes.setNamedItemNS(newAttr);
719
720     } // setAttributeNodeNS(Attr):Attr
721

722     /**
723      * Introduced in DOM Level 2.
724      */

725     public boolean hasAttributes() {
726         if (needsSyncData()) {
727             synchronizeData();
728         }
729         return (attributes != null && attributes.getLength() != 0);
730     }
731
732     /**
733      * Introduced in DOM Level 2.
734      */

735     public boolean hasAttribute(String JavaDoc name) {
736         return getAttributeNode(name) != null;
737     }
738
739     /**
740      * Introduced in DOM Level 2.
741      */

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

764     public NodeList JavaDoc getElementsByTagNameNS(String JavaDoc namespaceURI,
765                                            String JavaDoc localName) {
766         return new DeepNodeListImpl(this, namespaceURI, localName);
767     }
768
769     //
770
// Public methods
771
//
772

773     /**
774      * NON-DOM: Subclassed to flip the attributes' readonly switch as well.
775      * @see NodeImpl#setReadOnly
776      */

777     public void setReadOnly(boolean readOnly, boolean deep) {
778         super.setReadOnly(readOnly,deep);
779         if (attributes != null) {
780             attributes.setReadOnly(readOnly,true);
781         }
782     }
783
784     //
785
// Protected methods
786
//
787

788     /** Synchronizes the data (name and value) for fast nodes. */
789     protected void synchronizeData() {
790
791         // no need to sync in the future
792
needsSyncData(false);
793
794         // we don't want to generate any event for this so turn them off
795
boolean orig = ownerDocument.getMutationEvents();
796         ownerDocument.setMutationEvents(false);
797
798         // attributes
799
setupDefaultAttributes();
800
801         // set mutation events flag back to its original value
802
ownerDocument.setMutationEvents(orig);
803
804     } // synchronizeData()
805

806     /** Setup the default attributes. */
807     protected void setupDefaultAttributes() {
808         NamedNodeMapImpl defaults = getDefaultAttributes();
809         if (defaults != null) {
810             attributes = new AttributeMap(this, defaults);
811         }
812     }
813
814     /** Reconcile default attributes. */
815     protected void reconcileDefaultAttributes() {
816         NamedNodeMapImpl defaults = getDefaultAttributes();
817         if (defaults != null) {
818             attributes.reconcileDefaults(defaults);
819         }
820     }
821
822     /** Get the default attributes. */
823     protected NamedNodeMapImpl getDefaultAttributes() {
824
825         DocumentTypeImpl doctype =
826             (DocumentTypeImpl) ownerDocument.getDoctype();
827         if (doctype == null) {
828             return null;
829         }
830         ElementDefinitionImpl eldef =
831             (ElementDefinitionImpl)doctype.getElements()
832                                                .getNamedItem(getNodeName());
833         if (eldef == null) {
834             return null;
835         }
836         return (NamedNodeMapImpl) eldef.getAttributes();
837
838     } // getDefaultAttributes()
839

840
841     /* (non-Javadoc)
842      * @see org.w3c.dom.Element#getSchemaTypeInfo()
843      */

844     public TypeInfo JavaDoc getSchemaTypeInfo() {
845         // TODO Auto-generated method stub
846
return null;
847     }
848     /* (non-Javadoc)
849      * @see org.w3c.dom.Element#setIdAttribute(java.lang.String, boolean)
850      */

851     public void setIdAttribute(String JavaDoc name, boolean isId) throws DOMException JavaDoc {
852         // TODO Auto-generated method stub
853

854     }
855     /* (non-Javadoc)
856      * @see org.w3c.dom.Element#setIdAttributeNS(java.lang.String, java.lang.String, boolean)
857      */

858     public void setIdAttributeNS(String JavaDoc namespaceURI, String JavaDoc localName, boolean isId) throws DOMException JavaDoc {
859         // TODO Auto-generated method stub
860

861     }
862     /* (non-Javadoc)
863      * @see org.w3c.dom.Element#setIdAttributeNode(org.w3c.dom.Attr, boolean)
864      */

865     public void setIdAttributeNode(Attr JavaDoc idAttr, boolean isId) throws DOMException JavaDoc {
866         // TODO Auto-generated method stub
867

868     }
869
870 } // class ElementImpl
871
Popular Tags