1 package net.sf.saxon.pattern; 2 import net.sf.saxon.expr.Token; 3 import net.sf.saxon.om.NamePool; 4 import net.sf.saxon.om.NodeInfo; 5 import net.sf.saxon.type.AnyType; 6 import net.sf.saxon.type.SchemaType; 7 import net.sf.saxon.type.Type; 8 import net.sf.saxon.type.ItemType; 9 import net.sf.saxon.tinytree.TinyTree; 10 11 import java.util.Set ; 12 import java.util.HashSet ; 13 14 23 24 public class CombinedNodeTest extends NodeTest { 25 26 private NodeTest nodetest1; 27 private NodeTest nodetest2; 28 private int operator; 29 30 public CombinedNodeTest(NodeTest nt1, int operator, NodeTest nt2) { 31 nodetest1 = nt1; 32 this.operator = operator; 33 nodetest2 = nt2; 34 } 35 36 42 43 public boolean matches(int nodeType, int fingerprint, int annotation) { 44 switch (operator) { 45 case Token.UNION: 46 return nodetest1==null || 47 nodetest2==null || 48 nodetest1.matches(nodeType, fingerprint, annotation) || 49 nodetest2.matches(nodeType, fingerprint, annotation); 50 case Token.INTERSECT: 51 return (nodetest1==null || nodetest1.matches(nodeType, fingerprint, annotation)) && 52 (nodetest2==null || nodetest2.matches(nodeType, fingerprint, annotation)); 53 case Token.EXCEPT: 54 return (nodetest1==null || nodetest1.matches(nodeType, fingerprint, annotation)) && 55 !(nodetest2==null || nodetest2.matches(nodeType, fingerprint, annotation)); 56 default: 57 throw new IllegalArgumentException ("Unknown operator in Combined Node Test"); 58 } 59 } 60 61 72 73 public boolean matches(TinyTree tree, int nodeNr) { 74 switch (operator) { 75 case Token.UNION: 76 return nodetest1==null || 77 nodetest2==null || 78 nodetest1.matches(tree, nodeNr) || 79 nodetest2.matches(tree, nodeNr); 80 case Token.INTERSECT: 81 return (nodetest1==null || nodetest1.matches(tree, nodeNr)) && 82 (nodetest2==null || nodetest2.matches(tree, nodeNr)); 83 case Token.EXCEPT: 84 return (nodetest1==null || nodetest1.matches(tree, nodeNr)) && 85 !(nodetest2==null || nodetest2.matches(tree, nodeNr)); 86 default: 87 throw new IllegalArgumentException ("Unknown operator in Combined Node Test"); 88 } 89 } 90 91 97 98 public boolean matches(NodeInfo node) { 99 switch (operator) { 100 case Token.UNION: 101 return nodetest1==null || 102 nodetest2==null || 103 nodetest1.matches(node) || 104 nodetest2.matches(node); 105 case Token.INTERSECT: 106 return (nodetest1==null || nodetest1.matches(node)) && 107 (nodetest2==null || nodetest2.matches(node)); 108 case Token.EXCEPT: 109 return (nodetest1==null || nodetest1.matches(node)) && 110 !(nodetest2==null || nodetest2.matches(node)); 111 default: 112 throw new IllegalArgumentException ("Unknown operator in Combined Node Test"); 113 } 114 } 115 116 public String toString(NamePool pool) { 117 if (nodetest1 instanceof NameTest && operator==Token.INTERSECT) { 118 int kind = nodetest1.getPrimitiveType(); 119 String content = ""; 120 if (nodetest2 instanceof ContentTypeTest) { 121 content = ", " + ((ContentTypeTest)nodetest2).getSchemaType().getDisplayName(); 122 } 123 String name = pool.getDisplayName(nodetest1.getFingerprint()); 124 if (kind == Type.ELEMENT) { 125 return "element(" + name + content + ')'; 126 } else if (kind == Type.ATTRIBUTE) { 127 return "attribute(" + name + content + ')'; 128 } 129 } 130 String nt1 = (nodetest1==null ? "true()" : nodetest1.toString(pool)); 131 String nt2 = (nodetest2==null ? "true()" : nodetest2.toString(pool)); 132 return '(' + nt1 + ' ' + Token.tokens[operator] + ' ' + nt2 + ')'; 133 } 134 135 139 140 public ItemType getSuperType() { 141 switch (operator) { 142 case Token.UNION: 143 return Type.getCommonSuperType(nodetest1, nodetest2); 144 case Token.INTERSECT: 145 return nodetest1; 146 case Token.EXCEPT: 147 return nodetest1; 148 default: 149 throw new IllegalArgumentException ("Unknown operator in Combined Node Test"); 150 } 151 } 152 153 157 158 public int getNodeKindMask() { 159 switch (operator) { 160 case Token.UNION: 161 return nodetest1.getNodeKindMask() | nodetest2.getNodeKindMask(); 162 case Token.INTERSECT: 163 return nodetest1.getNodeKindMask() & nodetest2.getNodeKindMask(); 164 case Token.EXCEPT: 165 return nodetest1.getNodeKindMask(); 166 default: 167 return 0; 168 } 169 170 } 171 172 178 179 public int getPrimitiveType() { 180 int mask = getNodeKindMask(); 181 if (mask == (1<<Type.ELEMENT)) { 182 return Type.ELEMENT; 183 } 184 if (mask == (1<<Type.ATTRIBUTE)) { 185 return Type.ATTRIBUTE; 186 } 187 if (mask == (1<<Type.DOCUMENT)) { 188 return Type.DOCUMENT; 189 } 190 return Type.NODE; 191 } 192 193 198 199 public Set getRequiredNodeNames() { 200 Set s1 = nodetest1.getRequiredNodeNames(); 201 Set s2 = nodetest2.getRequiredNodeNames(); 202 if (s2 == null) { 203 return s1; 204 } 205 if (s1 == null) { 206 return s2; 207 } 208 switch (operator) { 209 case Token.UNION: { 210 Set result = new HashSet (s1); 211 result.addAll(s2); 212 return result; 213 } 214 case Token.INTERSECT: { 215 Set result = new HashSet (s1); 216 result.retainAll(s2); 217 return result; 218 } 219 case Token.EXCEPT: { 220 Set result = new HashSet (s1); 221 result.removeAll(s2); 222 return result; 223 } 224 default: 225 throw new UnsupportedOperationException (); 226 } 227 } 228 229 233 234 public SchemaType getContentType() { 235 SchemaType type1 = nodetest1.getContentType(); 236 SchemaType type2 = nodetest2.getContentType(); 237 if (type1.isSameType(type2)) return type1; 238 if (operator == Token.INTERSECT) { 239 if (type2 instanceof AnyType) { 240 return type1; 241 } 242 if (type1 instanceof AnyType) { 243 return type2; 244 } 245 } 246 return AnyType.getInstance(); 247 } 248 249 253 254 public int getFingerprint() { 255 int fp1 = nodetest1.getFingerprint(); 256 int fp2 = nodetest2.getFingerprint(); 257 if (fp1 == fp2) return fp1; 258 if (fp2 == -1 && operator==Token.INTERSECT) return fp1; 259 if (fp1 == -1 && operator==Token.INTERSECT) return fp2; 260 return -1; 261 } 262 263 266 267 public int hashCode() { 268 return nodetest1.hashCode() ^ nodetest2.hashCode(); 269 } 270 271 274 275 public double getDefaultPriority() { 276 return 0.25; 277 } 278 279 282 283 public NodeTest[] getComponentNodeTests() { 284 NodeTest[] tests = {nodetest1, nodetest2}; 285 return tests; 286 } 287 } 288 289 | Popular Tags |