001: package net.sf.saxon.pattern;
002:
003: import net.sf.saxon.om.NamePool;
004: import net.sf.saxon.om.NodeInfo;
005: import net.sf.saxon.type.ItemType;
006: import net.sf.saxon.type.TypeHierarchy;
007: import net.sf.saxon.tinytree.TinyTree;
008:
009: /**
010: * NodeTest is an interface that enables a test of whether a node has a particular
011: * name and type. A NamespaceTest matches the node type and the namespace URI.
012: *
013: * @author Michael H. Kay
014: */
015:
016: public final class NamespaceTest extends NodeTest {
017:
018: private NamePool namePool;
019: private int nodeKind;
020: private short uriCode;
021: private String uri;
022:
023: public NamespaceTest(NamePool pool, int nodeKind, String uri) {
024: namePool = pool;
025: this .nodeKind = nodeKind;
026: this .uri = uri;
027: this .uriCode = pool.allocateCodeForURI(uri);
028: }
029:
030: /**
031: * Test whether this node test is satisfied by a given node
032: * @param nodeType The type of node to be matched
033: * @param fingerprint identifies the expanded name of the node to be matched
034: */
035:
036: public boolean matches(int nodeType, int fingerprint, int annotation) {
037: if (fingerprint == -1)
038: return false;
039: if (nodeType != nodeKind)
040: return false;
041: return uriCode == namePool.getURICode(fingerprint);
042: }
043:
044: /**
045: * Test whether this node test is satisfied by a given node on a TinyTree. The node
046: * must be a document, element, text, comment, or processing instruction node.
047: * This method is provided
048: * so that when navigating a TinyTree a node can be rejected without
049: * actually instantiating a NodeInfo object.
050: *
051: * @param tree the TinyTree containing the node
052: * @param nodeNr the number of the node within the TinyTree
053: */
054:
055: public boolean matches(TinyTree tree, int nodeNr) {
056: int fingerprint = tree.getNameCode(nodeNr) & NamePool.FP_MASK;
057: if (fingerprint == -1)
058: return false;
059: if (tree.getNodeKind(nodeNr) != nodeKind)
060: return false;
061: return uriCode == namePool.getURICode(fingerprint);
062: }
063:
064: /**
065: * Test whether this node test is satisfied by a given node. This alternative
066: * method is used in the case of nodes where calculating the fingerprint is expensive,
067: * for example DOM or JDOM nodes.
068: * @param node the node to be matched
069: */
070:
071: public boolean matches(NodeInfo node) {
072: return node.getNodeKind() == nodeKind
073: && node.getURI().equals(uri);
074: }
075:
076: /**
077: * Determine the default priority of this node test when used on its own as a Pattern
078: */
079:
080: public final double getDefaultPriority() {
081: return -0.25;
082: }
083:
084: /**
085: * Determine the types of nodes to which this pattern applies. Used for optimisation.
086: * For patterns that match nodes of several types, return Type.NODE
087: * @return the type of node matched by this pattern. e.g. Type.ELEMENT or Type.TEXT
088: */
089:
090: public int getPrimitiveType() {
091: return nodeKind;
092: }
093:
094: /**
095: * Get the type from which this item type is derived by restriction. This
096: * is the supertype in the XPath type heirarchy, as distinct from the Schema
097: * base type: this means that the supertype of xs:boolean is xdt:anyAtomicType,
098: * whose supertype is item() (rather than xs:anySimpleType).
099: * <p>
100: * In fact the concept of "supertype" is not really well-defined, because the types
101: * form a lattice rather than a hierarchy. The only real requirement on this function
102: * is that it returns a type that strictly subsumes this type, ideally as narrowly
103: * as possible.
104: * @return the supertype, or null if this type is item()
105: * @param th
106: */
107:
108: public ItemType getSuperType(TypeHierarchy th) {
109: return NodeKindTest.makeNodeKindTest(nodeKind);
110: }
111:
112: /**
113: * Get a mask indicating which kinds of nodes this NodeTest can match. This is a combination
114: * of bits: 1<<Type.ELEMENT for element nodes, 1<<Type.TEXT for text nodes, and so on.
115: */
116:
117: public int getNodeKindMask() {
118: return 1 << nodeKind;
119: }
120:
121: public String toString() {
122: return '{' + namePool.getURIFromURICode(uriCode) + "}:*";
123: }
124:
125: /**
126: * Returns a hash code value for the object.
127: */
128:
129: public int hashCode() {
130: return uriCode << 5 + nodeKind;
131: }
132:
133: /**
134: * Indicates whether some other object is "equal to" this one.
135: */
136: public boolean equals(Object other) {
137: return other instanceof NamespaceTest
138: && ((NamespaceTest) other).namePool == namePool
139: && ((NamespaceTest) other).nodeKind == nodeKind
140: && ((NamespaceTest) other).uriCode == uriCode;
141: }
142:
143: }
144:
145: //
146: // The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
147: // you may not use this file except in compliance with the License. You may obtain a copy of the
148: // License at http://www.mozilla.org/MPL/
149: //
150: // Software distributed under the License is distributed on an "AS IS" basis,
151: // WITHOUT WARRANTY OF ANY KIND, either express or implied.
152: // See the License for the specific language governing rights and limitations under the License.
153: //
154: // The Original Code is: all this file.
155: //
156: // The Initial Developer of the Original Code is Michael H. Kay.
157: //
158: // Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
159: //
160: // Contributor(s): none.
161: //
|