Package org.apache.commons.configuration2.tree.xpath

# Class XPathExpressionEngine

java.lang.Object
org.apache.commons.configuration2.tree.xpath.XPathExpressionEngine

All Implemented Interfaces:
  `ExpressionEngine`

public class XPathExpressionEngine extends Object implements ExpressionEngine

A specialized implementation of the `ExpressionEngine` interface that is able to evaluate XPATH expressions.

This class makes use of Commons JXPath for handling XPath expressions and mapping them to the nodes of a hierarchical configuration. This makes the rich and powerful XPATH syntax available for accessing properties from a configuration object.

For selecting properties arbitrary XPATH expressions can be used, which select single or multiple configuration nodes. The associated `Configuration` instance will directly pass the specified property keys into this engine. If a key is not syntactically correct, an exception will be thrown.

For adding new properties, this expression engine uses a specific syntax: the "key" of a new property must consist of two parts that are separated by whitespace:

1. An XPATH expression selecting a single node, to which the new element(s) are to be added. This can be an arbitrary complex expression, but it must select exactly one node, otherwise an exception will be thrown.
2. The name of the new element(s) to be added below this parent node. Here either a single node name or a complete path of nodes (separated by the "/" character or "@" for an attribute) can be specified.

Some examples for valid keys that can be passed into the configuration's `addProperty()` method follow:

     "/tables/table[1] type"

This will add a new `type` node as a child of the first `table` element.

     "/tables/table[1] @type"

Similar to the example above, but this time a new attribute named `type` will be added to the first `table` element.

     "/tables table/fields/field/name"

This example shows how a complex path can be added. Parent node is the `tables` element. Here a new branch consisting of the nodes `table`, `fields`, `field`, and `name` will be added.

     "/tables table/fields/field@type"

This is similar to the last example, but in this case a complex path ending with an attribute is defined.

Note: This extended syntax for adding properties only works with the `addProperty()` method. `setProperty()` does not support creating new nodes this way.

From version 1.7 on, it is possible to use regular keys in calls to `addProperty()` (i.e. keys that do not have to contain a whitespace as delimiter). In this case the key is evaluated, and the biggest part pointing to an existing node is determined. The remaining part is then added as new path. As an example consider the key

     "tables/table[last()]/fields/field/name"

If the key does not point to an existing node, the engine will check the paths `"tables/table[last()]/fields/field"`, `"tables/table[last()]/fields"`, `"tables/table[last()]"`, and so on, until a key is found which points to a node. Let's assume that the last key listed above can be resolved in this way. Then from this key the following key is derived: `"tables/table[last()] fields/field/name"` by appending the remaining part after a whitespace. This key can now be processed using the original algorithm. Keys of this form can also be used with the `setProperty()` method. However, it is still recommended to use the old format because it makes explicit at which position new nodes should be added. For keys without a whitespace delimiter there may be ambiguities.

Since:
  1.3

- ## Constructor Summary

  Constructors
  Constructor
  Description
  `XPathExpressionEngine()`
  Creates a new instance of `XPathExpressionEngine` with default settings.

- ## Method Summary

  Modifier and Type
  Method
  Description
  `String`
  `attributeKey(String parentKey, String attributeName)`
  Returns the key of an attribute.
  `<T> String`
  `canonicalKey(T node, String parentKey, NodeHandler<T> handler)`
  Determines a "canonical" key for the specified node in the expression language supported by this implementation.
  `<T> String`
  `nodeKey(T node, String parentKey, NodeHandler<T> handler)`
  Returns the key for the specified node in the expression language supported by an implementation.
  `<T> NodeAddData<T>`
  `prepareAdd(T root, String key, NodeHandler<T> handler)`
  Returns information needed for an add operation.
  `<T> List<QueryResult<T>>`
  `query(T root, String key, NodeHandler<T> handler)`
  Finds the nodes and/or attributes that are matched by the specified key.

  ### Methods inherited from class java.lang.Object

  `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- ## Constructor Details

  - ### XPathExpressionEngine

    public XPathExpressionEngine()
    Creates a new instance of `XPathExpressionEngine` with default settings.

- ## Method Details

  - ### query

    public <T> List<QueryResult<T>> query(T root, String key, NodeHandler<T> handler)
    Finds the nodes and/or attributes that are matched by the specified key. This is the main method for interpreting property keys. An implementation must traverse the given root node and its children to find all results that are matched by the given key. If the key is not correct in the syntax provided by that implementation, it is free to throw a (runtime) exception indicating this error condition. The passed in `NodeHandler` can be used to gather the required information from the node object. This implementation interprets the passed in key as an XPATH expression.
    Specified by:
      `query` in interface `ExpressionEngine`
    Type Parameters:
      `T` - the type of the node to be processed
    Parameters:
      `root` - the root node of a hierarchy of nodes
      `key` - the key to be evaluated
      `handler` - the `NodeHandler` for accessing the node
    Returns:
      a list with the results that are matched by the key (should never be null)

  - ### nodeKey

    public <T> String nodeKey(T node, String parentKey, NodeHandler<T> handler)
    Returns the key for the specified node in the expression language supported by an implementation. This method is called whenever a property key for a node has to be constructed, e.g. by the `getKeys()` method. This implementation creates an XPATH expression that selects the given node (under the assumption that the passed in parent key is valid). As the `nodeKey()` implementation of `DefaultExpressionEngine` this method does not return indices for nodes. So all child nodes of a given parent with the same name have the same key.
    Specified by:
      `nodeKey` in interface `ExpressionEngine`
    Type Parameters:
      `T` - the type of the node to be processed
    Parameters:
      `node` - the node, for which the key must be constructed
      `parentKey` - the key of this node's parent (can be null for the root node)
      `handler` - the `NodeHandler` for accessing the node
    Returns:
      this node's key

  - ### attributeKey

    public String attributeKey(String parentKey, String attributeName)
    Description copied from interface: `ExpressionEngine`
    Returns the key of an attribute. The passed in `parentKey` must reference the parent node of the attribute. A concrete implementation must concatenate this parent key with the attribute name to a valid key for this attribute.
    Specified by:
      `attributeKey` in interface `ExpressionEngine`
    Parameters:
      `parentKey` - the key to the node owning this attribute
      `attributeName` - the name of the attribute in question
    Returns:
      the resulting key referencing this attribute

  - ### canonicalKey

    public <T> String canonicalKey(T node, String parentKey, NodeHandler<T> handler)
    Determines a "canonical" key for the specified node in the expression language supported by this implementation. This means that always a unique key if generated pointing to this specific node. For most concrete implementations, this means that an index is added to the node name to ensure that there are no ambiguities with child nodes having the same names. This implementation works similar to `nodeKey()`, but always adds an index expression to the resulting key.
    Specified by:
      `canonicalKey` in interface `ExpressionEngine`
    Type Parameters:
      `T` - the type of the node to be processed
    Parameters:
      `node` - the node, for which the key must be constructed
      `parentKey` - the key of this node's parent (can be null for the root node)
      `handler` - the `NodeHandler` for accessing the node
    Returns:
      the canonical key of this node

  - ### prepareAdd

    public <T> NodeAddData<T> prepareAdd(T root, String key, NodeHandler<T> handler)
    Returns information needed for an add operation. This method gets called when new properties are to be added to a configuration. An implementation has to interpret the specified key, find the parent node for the new elements, and provide all information about new nodes to be added. The expected format of the passed in key is explained in the class comment.
    Specified by:
      `prepareAdd` in interface `ExpressionEngine`
    Type Parameters:
      `T` - the type of the node to be processed
    Parameters:
      `root` - the root node
      `key` - the key for the new property
      `handler` - the `NodeHandler` for accessing the node
    Returns:
      an object with all information needed for the add operation