/** * get HashCode for comparing two expressions */ public int computeHashCode() { // generate an arbitrary hash code that depends on the axis and the node test int h = 9375162 + axis << 20; if (test != null) { h ^= test.getPrimitiveType() << 16; h ^= test.getFingerprint(); } return h; }
/** * Test whether a node conforms to the node type and name constraints. * Note that this returns true if the supplied node is null, this is a way of * terminating a loop. */ protected boolean conforms(NodeImpl node) { if (node==null || nodeTest==null) { return true; } return nodeTest.matches(node); }
/** * Determine the default priority of this node test when used on its own as a Pattern */ public final double getDefaultPriority() { return nodeTest.getDefaultPriority(); }
int kind = test.getPrimitiveType(); if (kind != Type.NODE) { if (!Axis.containsNodeKind(axis, kind)) { IntHashSet requiredNames = elementTest.getRequiredNodeNames(); if (requiredNames != null) { IntHashSet selected = test.getRequiredNodeNames(); if (selected != null && selected.intersect(requiredNames).isEmpty()) { env.issueWarning("Starting at a document node, the step is selecting an element whose name " + SchemaType contentType = ((NodeTest)contextItemType).getContentType(); if (contentType == AnyType.getInstance()) { int targetfp = test.getFingerprint();
int m1 = ((NodeTest)t1).getNodeKindMask(); int m2 = ((NodeTest)t2).getNodeKindMask(); if ((m1 & m2) == 0) { return DISJOINT; IntHashSet n1 = ((NodeTest)t1).getRequiredNodeNames(); // null means all names allowed IntHashSet n2 = ((NodeTest)t2).getRequiredNodeNames(); // null means all names allowed if (n1 == null) { if (n2 == null) { contentRelationship = SUBSUMES; } else { SchemaType s1 = ((NodeTest)t1).getContentType(); SchemaType s2 = ((NodeTest)t2).getContentType(); contentRelationship = schemaTypeRelationship(s1, s2);
/** * Determine the types of nodes to which this pattern applies. Used for optimisation. * For patterns that match nodes of several types, return Node.NODE * * @return the type of node matched by this pattern. e.g. Node.ELEMENT or Node.TEXT */ public int getNodeKind() { return nodeTest.getPrimitiveType(); }
/** * Determine the fingerprint of nodes to which this pattern applies. * Used for optimisation. * * @return the fingerprint of nodes matched by this pattern. */ public int getFingerprint() { return nodeTest.getFingerprint(); }
/** * Get the content type allowed by this NodeTest (that is, the type annotation of the matched nodes). * Return AnyType if there are no restrictions. The default implementation returns AnyType. */ public SchemaType getContentType() { SchemaType type1 = nodetest1.getContentType(); SchemaType type2 = nodetest2.getContentType(); if (type1.isSameType(type2)) return type1; if (operator == Token.INTERSECT) { if (type2 instanceof AnyType) { return type1; } if (type1 instanceof AnyType) { return type2; } } return AnyType.getInstance(); }
private String makeString(boolean forExport) { if (nodetest1 instanceof NameTest && operator == Token.INTERSECT) { int kind = nodetest1.getPrimitiveType(); String skind = kind == Type.ELEMENT ? "element(" : "attribute("; String content = ""; if (nodetest2 instanceof ContentTypeTest) { SchemaType schemaType = ((ContentTypeTest) nodetest2).getSchemaType(); if (forExport) { schemaType = schemaType.getNearestNamedType(); } content = ", " + schemaType.getEQName(); if (nodetest2.isNillable()) { content += "?"; } } String name = nodetest1.getMatchingNodeName().getEQName(); return skind + name + content + ')'; } else { String nt1 = nodetest1 == null ? "item()" : nodetest1.toString(); String nt2 = nodetest2 == null ? "item()" : nodetest2.toString(); return '(' + nt1 + ' ' + Token.tokens[operator] + ' ' + nt2 + ')'; } }
private lux.xpath.NodeTest nodeTestFor (NodeTest nodeTest) { if (nodeTest == null) { return new lux.xpath.NodeTest(ValueType.NODE); } if (nodeTest instanceof DocumentNodeTest) { return nodeTestFor ((DocumentNodeTest) nodeTest); } int nameCode = nodeTest.getFingerprint(); ValueType nodeType = valueTypeForItemType(nodeTest); if (nameCode >= 0) { // matches a single node name return new lux.xpath.NodeTest (nodeType, qnameForNameCode(nameCode)); } else { // matches multiple node names if (nodeTest instanceof LocalNameTest) { return new lux.xpath.NodeTest (nodeType, new QName(null, ((LocalNameTest)nodeTest).getLocalName(), "*")); } if (nodeTest instanceof NamespaceTest) { NamespaceTest namespaceTest = (NamespaceTest) nodeTest; String namespace = namespaceTest.getNamespaceURI(); String prefix = getPrefixForNamespace (namespace); QName qname = new QName(namespace, "*", prefix); addNamespaceDeclaration(qname); return new lux.xpath.NodeTest (nodeType, qname); } IntSet nameCodes = nodeTest.getRequiredNodeNames(); if (nameCodes == IntUniversalSet.getInstance()) { return new lux.xpath.NodeTest (nodeType); } throw new IllegalArgumentException("Unsupported node test: " + nodeTest.toString()); } }
public void addRule(NodeTestPattern pattern, Stripper.StripRuleTarget action, int precedence, int minImportPrecedence) throws XPathException { NodeTest test = pattern.getNodeTest(); double priority = test.getDefaultPriority(); Rule newRule = new Rule(pattern, action, precedence, minImportPrecedence, priority, sequence++); int prio = priority == 0 ? 2 : priority == -0.25 ? 1 : 0; newRule.setRank((precedence << 18) + (prio << 16) + sequence); if (test instanceof NodeKindTest) { newRule.setAlwaysMatches(true); anyElementRule = addRuleToList(newRule, anyElementRule, true); } else if (test instanceof NameTest) { newRule.setAlwaysMatches(true); int fp = test.getFingerprint(); NamePool pool = ((NameTest) test).getNamePool(); FingerprintedQName key = new FingerprintedQName(pool.getUnprefixedQName(fp), pool); Rule chain = namedElementRules.get(key); namedElementRules.put(key, addRuleToList(newRule, chain, true)); } else { unnamedElementRuleChain = addRuleToList(newRule, unnamedElementRuleChain, false); } }
contentRelationship = SUBSUMES; } else { SchemaType s1 = ((NodeTest) t1).getContentType(); SchemaType s2 = ((NodeTest) t2).getContentType(); contentRelationship = schemaTypeRelationship(s1, s2); boolean nillable1 = ((NodeTest) t1).isNillable(); boolean nillable2 = ((NodeTest) t2).isNillable();
/** * Get the set of node names allowed by this NodeTest. This is returned as a set of Integer fingerprints. * IntUniversalSet indicates that all names are permitted (i.e. that there are no constraints on the node name). */ /*@NotNull*/ public Optional<IntSet> getRequiredNodeNames() { Optional<IntSet> os1 = nodetest1.getRequiredNodeNames(); Optional<IntSet> os2 = nodetest2.getRequiredNodeNames(); if (os1.isPresent() && os2.isPresent()) { IntSet s1 = os1.get(); IntSet s2 = os2.get(); switch (operator) { case Token.UNION: { return Optional.of(s1.union(s2)); } case Token.INTERSECT: { return Optional.of(s1.intersect(s2)); } case Token.EXCEPT: { return Optional.of(s1.except(s2)); } default: throw new IllegalStateException(); } } else { return Optional.empty(); } }
/** * Test whether a node conforms to the node type and name constraints. * Note that this returns true if the supplied node is null, this is a way of * terminating a loop. * * @param node the node to be tested * @return true if the node matches the requested node type and name */ protected boolean conforms(/*@Nullable*/ NodeImpl node) { return node == null || nodeTest == null || nodeTest.matchesNode(node); }
/** * Get a mask indicating which kinds of nodes this NodeTest can match. This is a combination * of bits: 1<<Type.ELEMENT for element nodes, 1<<Type.TEXT for text nodes, and so on. */ public int getNodeKindMask() { switch (operator) { case Token.UNION: return nodetest1.getNodeKindMask() | nodetest2.getNodeKindMask(); case Token.INTERSECT: return nodetest1.getNodeKindMask() & nodetest2.getNodeKindMask(); case Token.EXCEPT: return nodetest1.getNodeKindMask(); default: return 0; } }
/** * Add the "parameters" of the type to a Dictionary containing the type information * in structured form */ public void addTypeDetails(DictionaryMap map) { if (nodetest1 instanceof NameTest && operator == Token.INTERSECT) { map.initialPut("n", new StringValue(nodetest1.getMatchingNodeName().getEQName())); if (nodetest2 instanceof ContentTypeTest) { SchemaType schemaType = ((ContentTypeTest) nodetest2).getSchemaType(); if (schemaType != Untyped.getInstance() && schemaType != BuiltInAtomicType.UNTYPED_ATOMIC) { map.initialPut("c", new StringValue(schemaType.getEQName() + (nodetest2.isNillable() ? "?" : ""))); } } } }
/** * Determine whether the content type (if present) is nillable * * @return true if the content test (when present) can match nodes that are nilled */ public boolean isNillable() { // this should err on the safe side return nodetest1.isNillable() && nodetest2.isNillable(); }
/** * Get the item type of the atomic values that will be produced when an item * of this type is atomized (assuming that atomization succeeds) */ public AtomicType getAtomizedItemType() { AtomicType type1 = nodetest1.getAtomizedItemType(); AtomicType type2 = nodetest2.getAtomizedItemType(); if (type1.isSameType(type2)) return type1; if (operator == Token.INTERSECT) { if (type2.equals(BuiltInAtomicType.ANY_ATOMIC)) { return type1; } if (type1.equals(BuiltInAtomicType.ANY_ATOMIC)) { return type2; } } return BuiltInAtomicType.ANY_ATOMIC; }
int kind = test.getPrimitiveType(); if (kind != Type.NODE) { if (!Axis.containsNodeKind(axis, kind)) { IntHashSet requiredNames = elementTest.getRequiredNodeNames(); if (requiredNames != null) { IntHashSet selected = test.getRequiredNodeNames(); if (selected != null && selected.intersect(requiredNames).isEmpty()) { env.issueWarning("Starting at a document node, the step is selecting an element whose name " + SchemaType contentType = ((NodeTest)contextItemType).getContentType(); if (contentType == AnyType.getInstance()) { int targetfp = test.getFingerprint();
int m1 = ((NodeTest)t1).getNodeKindMask(); int m2 = ((NodeTest)t2).getNodeKindMask(); if ((m1 & m2) == 0) { return DISJOINT; IntHashSet n1 = ((NodeTest)t1).getRequiredNodeNames(); // null means all names allowed IntHashSet n2 = ((NodeTest)t2).getRequiredNodeNames(); // null means all names allowed if (n1 == null) { if (n2 == null) { contentRelationship = SUBSUMES; } else { SchemaType s1 = ((NodeTest)t1).getContentType(); SchemaType s2 = ((NodeTest)t2).getContentType(); contentRelationship = schemaTypeRelationship(s1, s2);