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.sort.IntHashSet;
006: import net.sf.saxon.tinytree.TinyTree;
007: import net.sf.saxon.type.Type;
008:
009: /**
010: * NodeTest is an interface that enables a test of whether a node has a particular
011: * name and type. A SubstitutionGroupTest matches element nodes whose name is one of
012: * a given set of names: it is used for KindTests of the form schema-element(N) where all
013: * elements in a substitution group are to be matched.
014: *
015: * @author Michael H. Kay
016: */
017:
018: public class SubstitutionGroupTest extends NodeTest {
019:
020: private int fingerprint;
021: private IntHashSet group;
022:
023: /**
024: * Constructor
025: * @param group An IntSet containing Integer values representing the fingerprints
026: * of element names included in the substitution group
027: */
028:
029: public SubstitutionGroupTest(int fingerprint, IntHashSet group) {
030: this .group = group;
031: this .fingerprint = fingerprint;
032: }
033:
034: /**
035: * Test whether this node test is satisfied by a given node
036: * @param nodeKind The type of node to be matched
037: * @param nameCode identifies the expanded name of the node to be matched
038: */
039:
040: public boolean matches(int nodeKind, int nameCode, int annotation) {
041: return nodeKind == Type.ELEMENT
042: && group.contains(nameCode & NamePool.FP_MASK);
043: }
044:
045: /**
046: * Test whether this node test is satisfied by a given node on a TinyTree. The node
047: * must be a document, element, text, comment, or processing instruction node.
048: * This method is provided
049: * so that when navigating a TinyTree a node can be rejected without
050: * actually instantiating a NodeInfo object.
051: *
052: * @param tree the TinyTree containing the node
053: * @param nodeNr the number of the node within the TinyTree
054: * @return true if the node matches the NodeTest, otherwise false
055: */
056:
057: public boolean matches(TinyTree tree, int nodeNr) {
058: return tree.getNodeKind(nodeNr) == Type.ELEMENT
059: && group.contains(tree.getNameCode(nodeNr)
060: & NamePool.FP_MASK);
061: }
062:
063: /**
064: * Test whether this node test is satisfied by a given node. This alternative
065: * method is used in the case of nodes where calculating the fingerprint is expensive,
066: * for example DOM or JDOM nodes.
067: * @param node the node to be matched
068: */
069:
070: public boolean matches(NodeInfo node) {
071: return node.getNodeKind() == Type.ELEMENT
072: && group.contains(node.getFingerprint());
073: }
074:
075: /**
076: * Determine the default priority of this node test when used on its own as a Pattern
077: */
078:
079: public final double getDefaultPriority() {
080: return 0.0;
081: }
082:
083: /**
084: * Determine the types of nodes to which this pattern applies. Used for optimisation.
085: * For patterns that match nodes of several types, return Type.NODE
086: * @return the type of node matched by this pattern. e.g. Type.ELEMENT or Type.TEXT
087: */
088:
089: public int getPrimitiveType() {
090: return Type.ELEMENT;
091: }
092:
093: /**
094: * Get a mask indicating which kinds of nodes this NodeTest can match. This is a combination
095: * of bits: 1<<Type.ELEMENT for element nodes, 1<<Type.TEXT for text nodes, and so on.
096: */
097:
098: public int getNodeKindMask() {
099: return 1 << Type.ELEMENT;
100: }
101:
102: /**
103: * Get the set of node names allowed by this NodeTest. This is returned as a set of Integer fingerprints.
104: * A null value indicates that all names are permitted (i.e. that there are no constraints on the node name.
105: * The default implementation returns null.
106: */
107:
108: public IntHashSet getRequiredNodeNames() {
109: return group;
110: }
111:
112: /**
113: * Get the fingerprint of the head of the substitution group
114: * @return the fingerprint of the head of the substitution group
115: */
116:
117: public int getHeadFingerprint() {
118: return fingerprint;
119: }
120:
121: public String toString(NamePool pool) {
122: return "schema-element(" + pool.getDisplayName(fingerprint)
123: + ')';
124: }
125:
126: /**
127: * Returns a hash code value for the object.
128: */
129:
130: public int hashCode() {
131: return fingerprint;
132: }
133:
134: public boolean equals(Object other) {
135: return other instanceof SubstitutionGroupTest
136: && ((SubstitutionGroupTest) other).fingerprint == fingerprint;
137: }
138:
139: }
140:
141: //
142: // The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
143: // you may not use this file except in compliance with the License. You may obtain a copy of the
144: // License at http://www.mozilla.org/MPL/
145: //
146: // Software distributed under the License is distributed on an "AS IS" basis,
147: // WITHOUT WARRANTY OF ANY KIND, either express or implied.
148: // See the License for the specific language governing rights and limitations under the License.
149: //
150: // The Original Code is: all this file.
151: //
152: // The Initial Developer of the Original Code is Michael H. Kay.
153: //
154: // Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
155: //
156: // Contributor(s): none.
157: //
|