net.sf.saxon.trans
Class KeyManager

java.lang.Object
  extended by net.sf.saxon.trans.KeyManager
All Implemented Interfaces:
Serializable

public class KeyManager
extends Object
implements Serializable

KeyManager manages the set of key definitions in a stylesheet, and the indexes associated with these key definitions. It handles xsl:sort-key as well as xsl:key definitions.

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.

Author:
Michael H. Kay
See Also:
Serialized Form

Constructor Summary
KeyManager(Configuration config)
          Create a KeyManager and initialise variables
 
Method Summary
 void addKeyDefinition(StructuredQName keyName, KeyDefinition keydef, 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 getKeyDefinitionSet(StructuredQName qName)
          Get all the key definitions that match a particular name
 int getNumberOfKeyDefinitions()
          Get the number of distinctly-named key definitions
 void preRegisterKeyDefinition(StructuredQName keyName)
          Pre-register a key definition.
 SequenceIterator<NodeInfo> selectByKey(KeyDefinitionSet keySet, DocumentInfo doc, AtomicValue soughtValue, XPathContext context)
          Get the nodes with a given key value
 SequenceIterator selectByKey(StructuredQName keyName, DocumentInfo doc, AtomicValue soughtValue, XPathContext context)
          Get the nodes with a given key value.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

KeyManager

public KeyManager(Configuration config)
Create a KeyManager and initialise variables

Parameters:
config - the Saxon configuration
Method Detail

preRegisterKeyDefinition

public void preRegisterKeyDefinition(StructuredQName keyName)
Pre-register a key definition. This simply registers that a key with a given name exists, without providing any details.

Parameters:
keyName - the name of the key to be pre-registered

addKeyDefinition

public void addKeyDefinition(StructuredQName keyName,
                             KeyDefinition keydef,
                             Configuration config)
                      throws XPathException
Register a key definition. Note that multiple key definitions with the same name are allowed

Parameters:
keyName - Structured QName representing the name of the key
keydef - The details of the key's definition
config - The configuration
Throws:
XPathException - if this key definition is inconsistent with existing key definitions having the same name

getKeyDefinitionSet

public KeyDefinitionSet getKeyDefinitionSet(StructuredQName qName)
Get all the key definitions that match a particular name

Parameters:
qName - The name of the required key
Returns:
The set of key definitions of the named key if there are any, or null otherwise.

selectByKey

public SequenceIterator selectByKey(StructuredQName keyName,
                                    DocumentInfo doc,
                                    AtomicValue soughtValue,
                                    XPathContext context)
                             throws XPathException
Get the nodes with a given key value. This method is called from XQuery compiled code

Parameters:
keyName - key name used in the call to the key() function
doc - The source document in question
soughtValue - The required key value
context - The dynamic context, needed only the first time when the key is being built
Returns:
an iteration of the selected nodes, always in document order with no duplicates
Throws:
XPathException

selectByKey

public SequenceIterator<NodeInfo> selectByKey(KeyDefinitionSet keySet,
                                              DocumentInfo doc,
                                              AtomicValue soughtValue,
                                              XPathContext context)
                                       throws XPathException
Get the nodes with a given key value

Parameters:
keySet - The set of key definitions identified by the key name used in the call to the key() function
doc - The source document in question
soughtValue - The required key value
context - The dynamic context, needed only the first time when the key is being built
Returns:
an iteration of the selected nodes, always in document order with no duplicates
Throws:
XPathException

clearDocumentIndexes

public void clearDocumentIndexes(DocumentInfo doc)
Clear all the indexes for a given document. This is currently done whenever updates are applied to the document, because updates can potentially invalidate the indexes.

Parameters:
doc - the document whose indexes are to be invalidated

getNumberOfKeyDefinitions

public int getNumberOfKeyDefinitions()
Get the number of distinctly-named key definitions

Returns:
the number of key definition sets (where the key definitions in one set share the same name)

explainKeys

public void explainKeys(ExpressionPresenter out)
Diagnostic output explaining the keys

Parameters:
out - the expression presenter that will display the information


Copyright (c) 2004-2011 Saxonica Limited. All rights reserved.