KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > icl > saxon > tinytree > TinyElementImpl


1 package com.icl.saxon.tinytree;
2 import com.icl.saxon.om.*;
3 import com.icl.saxon.tree.DOMExceptionImpl;
4 import com.icl.saxon.expr.NodeSetExtent;
5 import com.icl.saxon.expr.XPathException;
6 import com.icl.saxon.om.Axis;
7 import com.icl.saxon.output.Outputter;
8 import com.icl.saxon.pattern.NameTest;
9 import com.icl.saxon.pattern.NamespaceTest;
10 import com.icl.saxon.pattern.AnyNodeTest;
11
12 import javax.xml.transform.TransformerException JavaDoc;
13
14 import org.w3c.dom.Element JavaDoc;
15 import org.w3c.dom.Attr JavaDoc;
16 import org.w3c.dom.Node JavaDoc;
17 import org.w3c.dom.NodeList JavaDoc;
18 import org.w3c.dom.DOMException JavaDoc;
19
20 /**
21   * A node in the XML parse tree representing an XML element.<P>
22   * This class is an implementation of NodeInfo and also implements the
23   * DOM Element interface
24   * @author <A HREF="mailto:mhkay@iclway.co.uk>Michael H. Kay</A>
25   */

26
27 final class TinyElementImpl extends TinyParentNodeImpl
28     implements Element JavaDoc {
29
30     /**
31     * Constructor
32     */

33     
34     public TinyElementImpl(TinyDocumentImpl doc, int nodeNr) {
35         this.document = doc;
36         this.nodeNr = nodeNr;
37     }
38
39     /**
40     * Return the type of node.
41     * @return NodeInfo.ELEMENT
42     */

43
44     public final short getNodeType() {
45         return ELEMENT;
46     }
47
48     /**
49     * Get the base URI of this element node. This will be the same as the System ID unless
50     * xml:base has been used.
51     */

52
53     public String JavaDoc getBaseURI() {
54         String JavaDoc xmlBase = getAttributeValue(Namespace.XML, "base");
55         if (xmlBase!=null) {
56             return xmlBase;
57         }
58         String JavaDoc startSystemId = getSystemId();
59         NodeInfo parent = getParent();
60         String JavaDoc parentSystemId = parent.getSystemId();
61         if (startSystemId.equals(parentSystemId)) {
62             return parent.getBaseURI();
63         } else {
64             return startSystemId;
65         }
66     }
67
68     /**
69     * Output all namespace nodes associated with this element.
70     * @param out The relevant outputter
71     * @param includeAncestors True if namespaces associated with ancestor
72     * elements must also be output; false if these are already known to be
73     * on the result tree.
74     */

75
76     public void outputNamespaceNodes(Outputter out, boolean includeAncestors)
77                 throws TransformerException JavaDoc {
78
79         int ns = document.length[nodeNr]; // by convention
80
if (ns>0 ) {
81             while (ns < document.numberOfNamespaces &&
82                     document.namespaceParent[ns] == nodeNr ) {
83                 int nscode = document.namespaceCode[ns];
84                 out.writeNamespaceDeclaration(nscode);
85                 ns++;
86             }
87         }
88
89         // now add the namespaces defined on the ancestor nodes. We rely on the outputter
90
// to eliminate multiple declarations of the same prefix
91

92         if (includeAncestors && document.isUsingNamespaces()) {
93             getParent().outputNamespaceNodes(out, true);
94             // terminates when the parent is a root node
95
}
96     }
97     
98     /**
99      * Returns whether this node (if it is an element) has any attributes.
100      * @return <code>true</code> if this node has any attributes,
101      * <code>false</code> otherwise.
102      * @since DOM Level 2
103      */

104     
105     public boolean hasAttributes() {
106         return document.offset[nodeNr] >= 0;
107     }
108     
109     /**
110      * Find the value of a given attribute of this node. <BR>
111      * This method is defined on all nodes to meet XSL requirements, but for nodes
112      * other than elements it will always return null.
113      * @param uri the namespace uri of an attribute
114      * @param localName the local name of an attribute
115      * @return the value of the attribute, if it exists, otherwise null
116      */

117
118     public String JavaDoc getAttributeValue( String JavaDoc uri, String JavaDoc localName ) {
119         int f = document.getNamePool().getFingerprint(uri, localName);
120         return getAttributeValue(f);
121     }
122
123     /**
124     * Get the value of a given attribute of this node
125     * @param fingerprint The fingerprint of the attribute name
126     * @return the attribute value if it exists or null if not
127     */

128     
129     public String JavaDoc getAttributeValue(int fingerprint) {
130         int a = document.offset[nodeNr];
131         if (a<0) return null;
132         while (a < document.numberOfAttributes && document.attParent[a] == nodeNr) {
133             if ((document.attCode[a] & 0xfffff) == fingerprint ) {
134                 return document.attValue[a];
135             }
136             a++;
137         }
138         return null;
139     }
140
141     /**
142     * Make an attribute node for a given attribute of this element
143     * @param index The relative position of the attribute, counting from zero. This
144     * is trusted to be in range.
145     */

146
147     public TinyAttributeImpl makeAttributeNode(int index) {
148         int a = document.offset[nodeNr];
149         if (a<0) return null;
150         return document.getAttributeNode(a+index);
151     }
152    
153     /**
154     * Set the value of an attribute on the current element. This affects subsequent calls
155     * of getAttribute() for that element.
156     * @param name The name of the attribute to be set. Any prefix is interpreted relative
157     * to the namespaces defined for this element.
158     * @param value The new value of the attribute. Set this to null to remove the attribute.
159     */

160     
161     public void setAttribute(String JavaDoc name, String JavaDoc value ) throws DOMException JavaDoc {
162         throw new DOMExceptionImpl((short)9999, "Saxon DOM is not updateable");
163     }
164
165     /**
166     * Copy this node to a given outputter (supporting xsl:copy-of)
167     */

168
169     public void copy(Outputter out) throws TransformerException JavaDoc {
170         copy(out, true);
171     }
172
173     /**
174     * Copy this node to a given outputter
175     * @param allNamespaces true if all namespace nodes must be copied; false
176     * if namespace nodes for the parent element are already on the result tree
177     */

178
179     public void copy(Outputter out, boolean allNamespaces) throws TransformerException JavaDoc {
180         
181         // TODO: this could be optimized by walking all the descendants in order,
182
// instead of doing a recursive tree walk. It would be necessary to maintain
183
// a stack, so that end tags could be written when the depth decreases.
184

185         int nc = getNameCode();
186         out.writeStartTag(nc);
187
188         // output the namespaces
189

190         outputNamespaceNodes(out, allNamespaces);
191
192         // output the attributes
193

194         int a = document.offset[nodeNr];
195         if (a >= 0) {
196             while (a < document.numberOfAttributes && document.attParent[a] == nodeNr) {
197                 document.getAttributeNode(a).copy(out);
198                 a++;
199             }
200         }
201
202         // output the children
203

204         AxisEnumeration children =
205             getEnumeration(Axis.CHILD, AnyNodeTest.getInstance());
206                     
207         while (children.hasMoreElements()) {
208             NodeInfo next = children.nextElement();
209             if (next instanceof TinyElementImpl) {
210                 ((TinyElementImpl)next).copy(out, false);
211                           // no need to do all the namespaces again
212
} else {
213                 next.copy(out);
214             }
215         }
216         out.writeEndTag(nc);
217     }
218         
219 }
220
221 //
222
// The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
223
// you may not use this file except in compliance with the License. You may obtain a copy of the
224
// License at http://www.mozilla.org/MPL/
225
//
226
// Software distributed under the License is distributed on an "AS IS" basis,
227
// WITHOUT WARRANTY OF ANY KIND, either express or implied.
228
// See the License for the specific language governing rights and limitations under the License.
229
//
230
// The Original Code is: all this file.
231
//
232
// The Initial Developer of the Original Code is
233
// Michael Kay of International Computers Limited (mhkay@iclway.co.uk).
234
//
235
// Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
236
//
237
// Contributor(s): none.
238
//
239
Popular Tags