001: package net.sf.saxon.tree;
002:
003: import net.sf.saxon.event.LocationCopier;
004: import net.sf.saxon.event.Receiver;
005: import net.sf.saxon.om.*;
006: import net.sf.saxon.trans.XPathException;
007: import net.sf.saxon.type.Type;
008:
009: /**
010: * ElementImpl implements an element with no attributes or namespace declarations.<P>
011: * This class is an implementation of NodeInfo. For elements with attributes or
012: * namespace declarations, class ElementWithAttributes is used.
013: * @author Michael H. Kay
014: */
015:
016: public class ElementImpl extends ParentNodeImpl {
017:
018: private static final AttributeCollectionImpl emptyAtts = new AttributeCollectionImpl(
019: null);
020:
021: protected int nameCode;
022: protected DocumentImpl root;
023:
024: /**
025: * Construct an empty ElementImpl
026: */
027:
028: public ElementImpl() {
029: }
030:
031: /**
032: * Set the name code. Used when creating a dummy element in the Stripper
033: */
034:
035: public void setNameCode(int nameCode) {
036: this .nameCode = nameCode;
037: }
038:
039: /**
040: * Initialise a new ElementImpl with an element name
041: * @param nameCode Integer representing the element name, with namespaces resolved
042: * @param atts The attribute list: always null
043: * @param parent The parent node
044: * @param baseURI The base URI of the new element
045: * @param lineNumber The line number of the element in the source document
046: * @param sequenceNumber Integer identifying this element within the document
047: */
048:
049: public void initialise(int nameCode, AttributeCollectionImpl atts,
050: NodeInfo parent, String baseURI, int lineNumber,
051: int sequenceNumber) {
052: this .nameCode = nameCode;
053: this .parent = (ParentNodeImpl) parent;
054: this .sequence = sequenceNumber;
055: this .root = (DocumentImpl) parent.getDocumentRoot();
056: root.setLineNumber(sequenceNumber, lineNumber);
057: root.setSystemId(sequenceNumber, baseURI);
058: }
059:
060: /**
061: * Set the system ID of this node. This method is provided so that a NodeInfo
062: * implements the javax.xml.transform.Source interface, allowing a node to be
063: * used directly as the Source of a transformation
064: */
065:
066: public void setSystemId(String uri) {
067: root.setSystemId(sequence, uri);
068: }
069:
070: /**
071: * Get the root node
072: */
073:
074: public NodeInfo getRoot() {
075: return root;
076: }
077:
078: /**
079: * Get the root document node
080: */
081:
082: public DocumentInfo getDocumentRoot() {
083: return root;
084: }
085:
086: /**
087: * Get the system ID of the entity containing this element node.
088: */
089:
090: public final String getSystemId() {
091: return ((DocumentImpl) getDocumentRoot()).getSystemId(sequence);
092: }
093:
094: /**
095: * Get the base URI of this element node. This will be the same as the System ID unless
096: * xml:base has been used.
097: */
098:
099: public String getBaseURI() {
100: return Navigator.getBaseURI(this );
101: }
102:
103: /**
104: * Set the line number of the element within its source document entity
105: */
106:
107: public void setLineNumber(int line) {
108: ((DocumentImpl) getDocumentRoot())
109: .setLineNumber(sequence, line);
110: }
111:
112: /**
113: * Get the line number of the node within its source document entity
114: */
115:
116: public int getLineNumber() {
117: return ((DocumentImpl) getDocumentRoot())
118: .getLineNumber(sequence);
119: }
120:
121: /**
122: * Get the nameCode of the node. This is used to locate the name in the NamePool
123: */
124:
125: public int getNameCode() {
126: return nameCode;
127: }
128:
129: /**
130: * Get a character string that uniquely identifies this node
131: * @return a string.
132: */
133:
134: public String generateId() {
135: return getDocumentRoot().generateId() + 'e' + sequence;
136: }
137:
138: /**
139: * Output all namespace nodes associated with this element.
140: * @param out The relevant outputter
141: */
142:
143: public void sendNamespaceDeclarations(Receiver out,
144: boolean includeAncestors) throws XPathException {
145:
146: // just add the namespaces defined on the ancestor nodes. We rely on the outputter
147: // to eliminate multiple declarations of the same prefix
148:
149: if (includeAncestors) {
150: if (!(parent instanceof DocumentInfo)) {
151: parent.sendNamespaceDeclarations(out, true);
152: }
153: }
154: }
155:
156: /**
157: * Get all namespace undeclarations and undeclarations defined on this element.
158: *
159: * @param buffer If this is non-null, and the result array fits in this buffer, then the result
160: * may overwrite the contents of this array, to avoid the cost of allocating a new array on the heap.
161: * @return An array of integers representing the namespace declarations and undeclarations present on
162: * this element. For a node other than an element, return null. Otherwise, the returned array is a
163: * sequence of namespace codes, whose meaning may be interpreted by reference to the name pool. The
164: * top half word of each namespace code represents the prefix, the bottom half represents the URI.
165: * If the bottom half is zero, then this is a namespace undeclaration rather than a declaration.
166: * The XML namespace is never included in the list. If the supplied array is larger than required,
167: * then the first unused entry will be set to -1.
168: * <p/>
169: * <p>For a node other than an element, the method returns null.</p>
170: */
171:
172: public int[] getDeclaredNamespaces(int[] buffer) {
173: return EMPTY_NAMESPACE_LIST;
174: }
175:
176: /**
177: * Return the type of node.
178: * @return Type.ELEMENT
179: */
180:
181: public final int getNodeKind() {
182: return Type.ELEMENT;
183: }
184:
185: /**
186: * Get the attribute list for this element.
187: * @return The attribute list. This will not include any
188: * namespace attributes. The attribute names will be in expanded form, with prefixes
189: * replaced by URIs
190: */
191:
192: public AttributeCollection getAttributeList() {
193: return emptyAtts;
194: }
195:
196: /**
197: * Find the value of a given attribute of this element. <BR>
198: * This is a short-cut method; the full capability to examine
199: * attributes is offered via the getAttributeList() method. <BR>
200: * The attribute may either be one that was present in the original XML document,
201: * or one that has been set by the application using setAttribute(). <BR>
202: * @param name the name of an attribute. There must be no prefix in the name.
203: * @return the value of the attribute, if it exists, otherwise null
204: */
205:
206: // public String getAttributeValue( String name ) {
207: // return null;
208: // }
209:
210: /**
211: * Copy this node to a given outputter (supporting xsl:copy-of)
212: * @param out The outputter
213: * @param whichNamespaces indicates which namespaces should be output: all, none, or local
214: * namespaces only (those not declared on the parent element)
215: */
216:
217: public void copy(Receiver out, int whichNamespaces,
218: boolean copyAnnotations, int locationId)
219: throws XPathException {
220:
221: int typeCode = (copyAnnotations ? getTypeAnnotation() : -1);
222: if (locationId == 0 && out instanceof LocationCopier) {
223: out.setSystemId(getSystemId());
224: ((LocationCopier) out).setLineNumber(getLineNumber());
225: }
226: out.startElement(getNameCode(), typeCode, locationId, 0);
227:
228: // output the namespaces
229:
230: if (whichNamespaces != NO_NAMESPACES) {
231: sendNamespaceDeclarations(out,
232: whichNamespaces == ALL_NAMESPACES);
233: }
234:
235: // output the children
236:
237: int childNamespaces = (whichNamespaces == NO_NAMESPACES ? NO_NAMESPACES
238: : LOCAL_NAMESPACES);
239: NodeImpl next = (NodeImpl) getFirstChild();
240: while (next != null) {
241: next
242: .copy(out, childNamespaces, copyAnnotations,
243: locationId);
244: next = (NodeImpl) next.getNextSibling();
245: }
246:
247: out.endElement();
248: }
249:
250: }
251:
252: //
253: // The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
254: // you may not use this file except in compliance with the License. You may obtain a copy of the
255: // License at http://www.mozilla.org/MPL/
256: //
257: // Software distributed under the License is distributed on an "AS IS" basis,
258: // WITHOUT WARRANTY OF ANY KIND, either express or implied.
259: // See the License for the specific language governing rights and limitations under the License.
260: //
261: // The Original Code is: all this file.
262: //
263: // The Initial Developer of the Original Code is Michael H. Kay.
264: //
265: // Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
266: //
267: // Contributor(s): none.
268: //
|