001: package net.sf.saxon.tinytree;
002:
003: import net.sf.saxon.event.Receiver;
004: import net.sf.saxon.om.NodeInfo;
005: import net.sf.saxon.trans.XPathException;
006: import net.sf.saxon.type.Type;
007:
008: /**
009: * A node in the XML parse tree representing an attribute. Note that this is
010: * generated only "on demand", when the attribute is selected by a select pattern.<P>
011: * @author Michael H. Kay
012: */
013:
014: final class TinyAttributeImpl extends TinyNodeImpl {
015:
016: public TinyAttributeImpl(TinyTree tree, int nodeNr) {
017: this .tree = tree;
018: this .nodeNr = nodeNr;
019: }
020:
021: /**
022: * Get the parent node
023: */
024:
025: public NodeInfo getParent() {
026: return tree.getNode(tree.attParent[nodeNr]);
027: }
028:
029: /**
030: * Get the root node of the tree (not necessarily a document node)
031: *
032: * @return the NodeInfo representing the root of this tree
033: */
034:
035: public NodeInfo getRoot() {
036: NodeInfo parent = getParent();
037: if (parent == null) {
038: return this ; // doesn't happen - parentless attributes are represented by the Orphan class
039: } else {
040: return parent.getRoot();
041: }
042: }
043:
044: /**
045: * Get the node sequence number (in document order). Sequence numbers are monotonic but not
046: * consecutive. In this implementation, elements have a zero
047: * least-significant word, while attributes and namespaces use the same value in the top word as
048: * the containing element, and use the bottom word to hold
049: * a sequence number, which numbers namespaces first and then attributes.
050: */
051:
052: protected long getSequenceNumber() {
053: // need the variable as workaround for a Java HotSpot problem, reported 11 Oct 2000
054: long z = ((TinyNodeImpl) getParent()).getSequenceNumber()
055: + 0x8000
056: + (nodeNr - tree.alpha[tree.attParent[nodeNr]]);
057: return z;
058: // note the 0x8000 is to leave room for namespace nodes
059: }
060:
061: /**
062: * Return the type of node.
063: * @return Node.ATTRIBUTE
064: */
065:
066: public final int getNodeKind() {
067: return Type.ATTRIBUTE;
068: }
069:
070: /**
071: * Return the string value of the node.
072: * @return the attribute value
073: */
074:
075: public CharSequence getStringValueCS() {
076: return tree.attValue[nodeNr];
077: }
078:
079: /**
080: * Return the string value of the node.
081: * @return the attribute value
082: */
083:
084: public String getStringValue() {
085: return tree.attValue[nodeNr].toString();
086: }
087:
088: /**
089: * Get the fingerprint of the node, used for matching names
090: */
091:
092: public int getFingerprint() {
093: return tree.attCode[nodeNr] & 0xfffff;
094: }
095:
096: /**
097: * Get the name code of the node, used for finding names in the name pool
098: */
099:
100: public int getNameCode() {
101: return tree.attCode[nodeNr];
102: }
103:
104: /**
105: * Get the prefix part of the name of this node. This is the name before the ":" if any.
106: * @return the prefix part of the name. For an unnamed node, return null.
107: */
108:
109: public String getPrefix() {
110: int code = tree.attCode[nodeNr];
111: if ((code >> 20 & 0xff) == 0)
112: return "";
113: return tree.getNamePool().getPrefix(code);
114: }
115:
116: /**
117: * Get the display name of this node. For elements and attributes this is [prefix:]localname.
118: * For unnamed nodes, it is an empty string.
119: * @return The display name of this node.
120: * For a node with no name, return an empty string.
121: */
122:
123: public String getDisplayName() {
124: return tree.getNamePool().getDisplayName(tree.attCode[nodeNr]);
125: }
126:
127: /**
128: * Get the local name of this node.
129: * @return The local name of this node.
130: * For a node with no name, return an empty string.
131: */
132:
133: public String getLocalPart() {
134: return tree.getNamePool().getLocalName(tree.attCode[nodeNr]);
135: }
136:
137: /**
138: * Get the URI part of the name of this node.
139: * @return The URI of the namespace of this node. For the default namespace, return an
140: * empty string
141: */
142:
143: public final String getURI() {
144: return tree.getNamePool().getURI(tree.attCode[nodeNr]);
145: }
146:
147: /**
148: * Get the type annotation of this node, if any
149: * The bit {@link NodeInfo#IS_DTD_TYPE} (1<<30) will be set in the case of an attribute node if the type annotation
150: * is one of ID, IDREF, or IDREFS and this is derived from DTD rather than schema validation.
151: * Returns UNTYPED_ATOMIC if there is no type annotation
152: */
153:
154: public int getTypeAnnotation() {
155: return tree.getAttributeAnnotation(nodeNr);
156: }
157:
158: /**
159: * Generate id. Returns key of owning element with the attribute namecode as a suffix
160: */
161:
162: public String generateId() {
163: return (getParent()).generateId() + 'a' + tree.attCode[nodeNr];
164: // we previously used the attribute name. But this breaks the requirement
165: // that the result of generate-id consists entirely of alphanumeric ASCII
166: // characters
167: }
168:
169: /**
170: * Copy this node to a given outputter
171: */
172:
173: public void copy(Receiver out, int whichNamespaces,
174: boolean copyAnnotations, int locationId)
175: throws XPathException {
176: int nameCode = tree.attCode[nodeNr];
177: int typeCode = (copyAnnotations ? getTypeAnnotation() : -1);
178: out.attribute(nameCode, typeCode, getStringValue(), locationId,
179: 0);
180: }
181:
182: /**
183: * Get the line number of the node within its source document entity
184: */
185:
186: public int getLineNumber() {
187: return getParent().getLineNumber();
188: }
189:
190: }
191:
192: //
193: // The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
194: // you may not use this file except in compliance with the License. You may obtain a copy of the
195: // License at http://www.mozilla.org/MPL/
196: //
197: // Software distributed under the License is distributed on an "AS IS" basis,
198: // WITHOUT WARRANTY OF ANY KIND, either express or implied.
199: // See the License for the specific language governing rights and limitations under the License.
200: //
201: // The Original Code is: all this file.
202: //
203: // The Initial Developer of the Original Code is Michael H. Kay.
204: //
205: // Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
206: //
207: // Contributor(s): none.
208: //
|