KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > icl > saxon > tree > ElementImpl


1 package com.icl.saxon.tree;
2 import com.icl.saxon.om.NodeInfo;
3 import com.icl.saxon.om.DocumentInfo;
4 import com.icl.saxon.om.NamespaceException;
5 import com.icl.saxon.om.NamePool;
6 import com.icl.saxon.om.Namespace;
7 import com.icl.saxon.om.Name;
8 import com.icl.saxon.expr.NodeSetExtent;
9 import com.icl.saxon.output.Outputter;
10 import com.icl.saxon.pattern.NameTest;
11 import com.icl.saxon.pattern.NamespaceTest;
12
13 import java.util.Vector JavaDoc;
14 import org.w3c.dom.*;
15
16 import javax.xml.transform.TransformerException JavaDoc;
17
18 /**
19   * ElementImpl implements an element with no attributes or namespace declarations.<P>
20   * This class is an implementation of NodeInfo. For elements with attributes or
21   * namespace declarations, class ElementWithAttributes is used.
22   * @author <A HREF="mailto:mhkay@iclway.co.uk>Michael H. Kay</A>
23   */

24
25 // The name of the element and its attributes are now namespace-resolved by the
26
// parser. However, this class retains the ability to do namespace resolution for other
27
// names, for example variable and template names in a stylesheet.
28

29 public class ElementImpl extends ParentNodeImpl
30     implements Element {
31
32     private static AttributeCollection emptyAtts = new AttributeCollection((NamePool)null);
33     
34     protected int nameCode;
35     protected DocumentImpl root;
36
37     /**
38     * Construct an empty ElementImpl
39     */

40
41     public ElementImpl() {}
42     
43     /**
44     * Set the name code. Used when creating a dummy element in the Stripper
45     */

46     
47     public void setNameCode(int nameCode) {
48         this.nameCode = nameCode;
49     }
50
51     /**
52     * Initialise a new ElementImpl with an element name
53     * @param name The element name, with namespaces resolved
54     * @param atts The attribute list: always null
55     * @param parent The parent node
56     */

57
58     public void initialise(int nameCode, AttributeCollection atts, NodeInfo parent,
59                             String JavaDoc baseURI, int lineNumber, int sequenceNumber) {
60         this.nameCode = nameCode;
61         this.parent = (ParentNodeImpl)parent;
62         this.sequence = sequenceNumber;
63         this.root = (DocumentImpl)parent.getDocumentRoot();
64         root.setLineNumber(sequenceNumber, lineNumber);
65         root.setSystemId(sequenceNumber, baseURI);
66     }
67
68     /**
69     * Set the system ID of this node. This method is provided so that a NodeInfo
70     * implements the javax.xml.transform.Source interface, allowing a node to be
71     * used directly as the Source of a transformation
72     */

73     
74     public void setSystemId(String JavaDoc uri) {
75         root.setSystemId(sequence, uri);
76     }
77
78     /**
79     * Get the root node
80     */

81     
82     public DocumentInfo getDocumentRoot() {
83         return root;
84     }
85
86     /**
87     * Get the system ID of the entity containing this element node.
88     */

89
90     public final String JavaDoc getSystemId() {
91         return ((DocumentImpl)getDocumentRoot()).getSystemId(sequence);
92     }
93
94     /**
95     * Get the base URI of this element node. This will be the same as the System ID unless
96     * xml:base has been used.
97     */

98
99     public String JavaDoc getBaseURI() {
100         String JavaDoc xmlBase = getAttributeValue(Namespace.XML, "base");
101         if (xmlBase!=null) {
102             return xmlBase;
103         }
104         String JavaDoc startSystemId = getSystemId();
105         String JavaDoc parentSystemId = parent.getSystemId();
106         if (startSystemId.equals(parentSystemId)) {
107             return parent.getBaseURI();
108         } else {
109             return startSystemId;
110         }
111     }
112
113     /**
114     * Set the line number of the element within its source document entity
115     */

116
117     public void setLineNumber(int line) {
118         ((DocumentImpl)getDocumentRoot()).setLineNumber(sequence, line);
119     }
120
121
122     /**
123     * Get the line number of the node within its source document entity
124     */

125
126     public int getLineNumber() {
127         return ((DocumentImpl)getDocumentRoot()).getLineNumber(sequence);
128     }
129
130
131     /**
132     * Get the nameCode of the node. This is used to locate the name in the NamePool
133     */

134     
135     public int getNameCode() {
136         return nameCode;
137     }
138
139     /**
140     * Get a character string that uniquely identifies this node within this document
141     * (The calling code will prepend a document identifier)
142     * @return a string.
143     */

144
145     public String JavaDoc generateId() {
146         return "e" + sequence;
147     }
148
149     /**
150     * Search the NamespaceList for a given prefix, returning the corresponding URI.
151     * @param prefix The prefix to be matched. To find the default namespace, supply ""
152     * @return The URI code corresponding to this namespace. If it is an unnamed default namespace,
153     * return Namespace.NULL_CODE.
154     * @throws NamespaceException if the prefix has not been declared on this NamespaceList.
155     */

156
157     public short getURICodeForPrefix(String JavaDoc prefix) throws NamespaceException {
158         // this is actually never called; it's used only in a Stylesheet, and in a Stylesheet
159
// we always use the version on ElementWithAttributes
160
if (prefix.equals("xml")) return Namespace.XML_CODE;
161         if (parent.getNodeType()==NodeInfo.ROOT) {
162             if (prefix.equals("")) {
163                 return Namespace.NULL_CODE;
164             }
165             throw new NamespaceException(prefix);
166         } else {
167             return ((ElementImpl)parent).getURICodeForPrefix(prefix);
168         }
169     }
170
171     /**
172     * Search the NamespaceList for a given URI, returning the corresponding prefix.
173     * @param uri The URI to be matched.
174     * @return The prefix corresponding to this URI. If not found, return null. If there is
175     * more than one prefix matching the URI, the first one found is returned. If the URI matches
176     * the default namespace, return an empty string.
177     */

178
179     public String JavaDoc getPrefixForURI(String JavaDoc uri) {
180         if (parent.getNodeType()==NodeInfo.ROOT) {
181             return null;
182         } else {
183             return ((ElementImpl)parent).getPrefixForURI(uri);
184         }
185     }
186
187     /**
188     * Make a NameCode, using this Element as the context for namespace resolution.
189     * The name will be entered in the namepool: therefore this method should not be
190     * called once the name pool is sealed.
191     * @param qname The name as written, in the form "[prefix:]localname"
192     * @boolean useDefault Defines the action when there is no prefix. If true, use
193     * the default namespace URI (as for element names). If false, use no namespace URI
194     * (as for attribute names).
195     */

196
197     public final int makeNameCode(String JavaDoc qname, boolean useDefault)
198     throws NamespaceException {
199
200         NamePool namePool = getNamePool();
201         String JavaDoc prefix = Name.getPrefix(qname);
202         if (prefix.equals("")) {
203             short uriCode = 0;
204             
205             if (useDefault) {
206                 uriCode = getURICodeForPrefix(prefix);
207             }
208             
209             return namePool.allocate(prefix, uriCode, qname);
210
211         } else {
212             String JavaDoc localName = Name.getLocalName(qname);
213             short uriCode = getURICodeForPrefix(prefix);
214             return namePool.allocate(prefix, uriCode, localName);
215         }
216
217     }
218
219     /**
220     * Make the set of all namespace nodes associated with this element.
221     * @param owner The element owning these namespace nodes.
222     * @param list a Vector containing NamespaceImpl objects representing the namespaces
223     * in scope for this element; the method appends nodes to this Vector, which should
224     * initially be empty. Note that the returned list will never contain the XML namespace
225     * (to get this, the NamespaceEnumeration class adds it itself). The list WILL include
226     * an entry for the undeclaration xmlns=""; again it is the job of NamespaceEnumeration
227     * to ignore this, since it doesn't represent a true namespace node.
228     * @param addXML Add the XML namespace node to the list
229     */

230
231     public void addNamespaceNodes(ElementImpl owner, Vector JavaDoc list, boolean addXML) {
232         // just add the namespaces defined on the ancestor nodes
233

234         if (parent.getNodeType()!=NodeInfo.ROOT) {
235             ((ElementImpl)parent).addNamespaceNodes(owner, list, false);
236         }
237         if (addXML) {
238             int nsxml = (1<<16) + 1;
239             list.addElement(
240                 new NamespaceImpl(this, nsxml, list.size()+1)
241                 );
242         }
243     }
244     
245     /**
246     * Output all namespace nodes associated with this element.
247     * @param out The relevant outputter
248     */

249
250     public void outputNamespaceNodes(Outputter out, boolean includeAncestors) throws TransformerException JavaDoc {
251
252         // just add the namespaces defined on the ancestor nodes. We rely on the outputter
253
// to eliminate multiple declarations of the same prefix
254

255         if (includeAncestors) {
256             if (!(parent instanceof DocumentInfo)) {
257                 ((ElementImpl)parent).outputNamespaceNodes(out, true);
258             }
259         }
260     }
261     
262
263
264     /**
265     * Return the type of node.
266     * @return NodeInfo.ELEMENT
267     */

268
269     public final short getNodeType() {
270         return ELEMENT;
271     }
272     
273     /**
274     * Get the attribute list for this element.
275     * @return The attribute list. This will not include any
276     * namespace attributes. The attribute names will be in expanded form, with prefixes
277     * replaced by URIs
278     */

279     
280     public AttributeCollection getAttributeList() {
281         return emptyAtts;
282     }
283
284     /**
285      * Find the value of a given attribute of this element. <BR>
286      * This is a short-cut method; the full capability to examine
287      * attributes is offered via the getAttributeList() method. <BR>
288      * The attribute may either be one that was present in the original XML document,
289      * or one that has been set by the application using setAttribute(). <BR>
290      * @param name the name of an attribute. There must be no prefix in the name.
291      * @return the value of the attribute, if it exists, otherwise null
292      */

293
294     public String JavaDoc getAttributeValue( String JavaDoc name ) {
295         return null;
296     }
297
298    
299     /**
300     * Set the value of an attribute on the current element.
301     * @throws DOMException (always): the Saxon tree is immutable
302     */

303     
304     public void setAttribute(String JavaDoc name, String JavaDoc value ) throws DOMException {
305         disallowUpdate();
306     }
307        
308     /**
309     * Copy this node to a given outputter (supporting xsl:copy-of)
310     */

311
312     public void copy(Outputter out) throws TransformerException JavaDoc {
313         copy(out, true);
314     }
315
316     /**
317     * Copy this node to a given outputter (supporting xsl:copy-of)
318     * @param out The outputter
319     * @param allNamespaces true if namespaces for ancestor nodes must be output
320     */

321
322     public void copy(Outputter out, boolean allNamespaces) throws TransformerException JavaDoc {
323         int nc = getNameCode();
324         out.writeStartTag(nc);
325
326         // output the namespaces
327

328         outputNamespaceNodes(out, allNamespaces);
329
330         // output the children
331

332         NodeImpl next = (NodeImpl)getFirstChild();
333         while (next!=null) {
334             if (next instanceof ElementImpl) {
335                 ((ElementImpl)next).copy(out, false);
336             } else {
337                 next.copy(out);
338             }
339             next = (NodeImpl)next.getNextSibling();
340         }
341
342         out.writeEndTag(nc);
343     }
344         
345 }
346
347 //
348
// The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
349
// you may not use this file except in compliance with the License. You may obtain a copy of the
350
// License at http://www.mozilla.org/MPL/
351
//
352
// Software distributed under the License is distributed on an "AS IS" basis,
353
// WITHOUT WARRANTY OF ANY KIND, either express or implied.
354
// See the License for the specific language governing rights and limitations under the License.
355
//
356
// The Original Code is: all this file.
357
//
358
// The Initial Developer of the Original Code is
359
// Michael Kay of International Computers Limited (mhkay@iclway.co.uk).
360
//
361
// Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
362
//
363
// Contributor(s): none.
364
//
365
Popular Tags