public class KeyManager extends Object
The memory management in this class is subtle, with extensive use of weak references. The idea is that an index should continue to exist in memory so long as both the compiled stylesheet and the source document exist in memory: if either is removed, the index should go too. The document itself holds no reference to the index. The compiled stylesheet (which owns the KeyManager) holds a weak reference to the index. The index, of course, holds strong references to the nodes in the document. The Controller holds a strong reference to the list of indexes used for each document, so that indexes remain in memory for the duration of a transformation even if the documents themselves are garbage collected.
Potentially there is a need for more than one index for a given key name, depending on the primitive type of the value provided to the key() function. An index is built corresponding to the type of the requested value; if subsequently the key() function is called with the same name and a different type of value, then a new index is built.
For XSLT-defined keys, equality matching follows the rules of the eq operator, which means that untypedAtomic values are treated as strings. In backwards compatibility mode, all values are converted to strings.
This class is also used for internal indexes constructed (a) to support the idref() function, and (b) (in Saxon-EE only) to support filter expressions of the form /a/b/c[d=e], where the path expression being filtered must be a single-document context-free path rooted at a document node, where exactly one of d and e must be dependent on the focus, and where certain other conditions apply such as the filter predicate not being positional. The operator in this case may be either "=" or "eq". If it is "eq", then the semantics are very similar to xsl:key indexes, except that use of non-comparable types gives an error rather than a non-match. If the operator is "=", however, then the rules for handling untypedAtomic values are different: these must be converted to the type of the other operand. In this situation the following rules apply. Assume that the predicate is [use=value], where use is dependent on the focus (the indexed value), and value is the sought value.
Constructor and Description |
---|
KeyManager(Configuration config)
Create a KeyManager and initialise variables
|
Modifier and Type | Method and Description |
---|---|
void |
addKeyDefinition(StructuredQName keyName,
KeyDefinition keydef,
boolean reusable,
Configuration config)
Register a key definition.
|
void |
clearDocumentIndexes(DocumentInfo doc)
Clear all the indexes for a given document.
|
void |
explainKeys(ExpressionPresenter out)
Diagnostic output explaining the keys
|
KeyDefinitionSet |
findKeyDefinition(PathFinder finder,
Expression use,
String collationName)
Look for a key definition that matches a proposed new key
|
Collection<KeyDefinitionSet> |
getAllKeyDefinitionSets()
Get all the key definition sets
|
KeyDefinitionSet |
getKeyDefinitionSet(StructuredQName qName)
Get all the key definitions that match a particular name
|
int |
getNumberOfKeyDefinitions()
Get the number of distinctly-named key definitions
|
Map<AtomicMatchKey,List<NodeInfo>> |
obtainIndex(KeyDefinitionSet keySet,
DocumentInfo doc,
XPathContext context,
HashSet<BuiltInAtomicType> foundItemTypes,
BuiltInAtomicType itemType) |
void |
preRegisterKeyDefinition(StructuredQName keyName)
Pre-register a key definition.
|
SequenceIterator |
selectByKey(KeyDefinitionSet keySet,
DocumentInfo doc,
AtomicValue soughtValue,
XPathContext context)
Get the nodes with a given key value
|
public KeyManager(Configuration config)
config
- the Saxon configurationpublic void preRegisterKeyDefinition(StructuredQName keyName)
keyName
- the name of the key to be pre-registeredpublic void addKeyDefinition(StructuredQName keyName, KeyDefinition keydef, boolean reusable, Configuration config) throws XPathException
keyName
- Structured QName representing the name of the keykeydef
- The details of the key's definitionreusable
- Set to true if indexes using this key definition can be used across multiple transformations, false if
the indexes need to be rebuilt for each transformation. Indexes are not reusable if the key definition contains references
to global variables or parameters, or calls used-defined functions or templates that might contain such references.config
- The configurationXPathException
- if this key definition is inconsistent with existing key definitions having the same namepublic KeyDefinitionSet getKeyDefinitionSet(StructuredQName qName)
qName
- The name of the required keypublic KeyDefinitionSet findKeyDefinition(PathFinder finder, Expression use, String collationName)
finder
- matches/selects the nodes to be indexeduse
- computes the value on which the nodes are indexedcollationName
- collation to be usedpublic SequenceIterator selectByKey(KeyDefinitionSet keySet, DocumentInfo doc, AtomicValue soughtValue, XPathContext context) throws XPathException
keySet
- The set of key definitions identified by the key name used in the call to the key() functiondoc
- The source document in questionsoughtValue
- The required key valuecontext
- The dynamic context, needed only the first time when the key is being builtXPathException
- if a dynamic error is encounteredpublic Map<AtomicMatchKey,List<NodeInfo>> obtainIndex(KeyDefinitionSet keySet, DocumentInfo doc, XPathContext context, HashSet<BuiltInAtomicType> foundItemTypes, BuiltInAtomicType itemType) throws XPathException
XPathException
public void clearDocumentIndexes(DocumentInfo doc)
doc
- the document whose indexes are to be invalidatedpublic Collection<KeyDefinitionSet> getAllKeyDefinitionSets()
public int getNumberOfKeyDefinitions()
public void explainKeys(ExpressionPresenter out)
out
- the expression presenter that will display the informationCopyright (c) 2004-2014 Saxonica Limited. All rights reserved.