org.modeshape.jcr.spi.index.provider

## Class IndexProvider

- java.lang.Object
- - org.modeshape.jcr.spi.index.provider.IndexProvider

- Direct Known Subclasses:
    LocalIndexProvider

      public abstract class IndexProvider
      extends Object

  A component that provides access to and manages a set of `indexes` that are described/defined with `IndexDefinition` objects via the session's `IndexManager`. This provider uses each `IndexDefinition` to define and manage the `Index`es for each workspace identified by the definition. Much of this management is the same for all providers, so this implementation provides much of that functionality. What each custom provider must do, then, is respond to the `createIndex(org.modeshape.jcr.api.index.IndexDefinition, java.lang.String, org.modeshape.jcr.NodeTypes.Supplier, org.modeshape.jcr.cache.change.ChangeSetAdapter.NodeTypePredicate, org.modeshape.jcr.spi.index.IndexFeedback)`, `updateIndex(org.modeshape.jcr.api.index.IndexDefinition, org.modeshape.jcr.api.index.IndexDefinition, org.modeshape.jcr.spi.index.provider.ManagedIndex, java.lang.String, org.modeshape.jcr.NodeTypes.Supplier, org.modeshape.jcr.cache.change.ChangeSetAdapter.NodeTypePredicate, org.modeshape.jcr.spi.index.IndexFeedback)`, `removeIndex(org.modeshape.jcr.api.index.IndexDefinition, org.modeshape.jcr.spi.index.provider.ManagedIndex, java.lang.String)` methods and return an appropriate `ManagedIndex` object that behaves as described by the method parameters. While the `Index` represents the functionality needed by the query engine, the `ManagedIndex` is the lowest-level and simplest interface to encapsulate the behavior of a single index managed by this provider. for each Only basic functionality is provided, and subclasses specialize the behavior by overriding several abstract methods.

  Upon startup, the repository examines its configuration and sets up each of the index providers using this sequence:

  1. Instantiation of a providers via no-arg constructor
  2. Reflectively set each of the member fields of the provider instance, based upon the provider configuration's properties
  3. Call the `initialize()` method. This method is final and delegates to `doInitialize()`, which can be specialized for any implementation-specific startup behavior.
  4. Notify this provider of all of its `IndexDefinition`s, whether they are defined in the configuration or persisted in the repository's system area, by calling `notify(IndexDefinitionChanges, ChangeBus, org.modeshape.jcr.NodeTypes.Supplier, Set, IndexFeedback)`. This method processes all of the definition changes, and based upon the available workspaces, calls the `createIndex(org.modeshape.jcr.api.index.IndexDefinition, java.lang.String, org.modeshape.jcr.NodeTypes.Supplier, org.modeshape.jcr.cache.change.ChangeSetAdapter.NodeTypePredicate, org.modeshape.jcr.spi.index.IndexFeedback)`, `updateIndex(org.modeshape.jcr.api.index.IndexDefinition, org.modeshape.jcr.api.index.IndexDefinition, org.modeshape.jcr.spi.index.provider.ManagedIndex, java.lang.String, org.modeshape.jcr.NodeTypes.Supplier, org.modeshape.jcr.cache.change.ChangeSetAdapter.NodeTypePredicate, org.modeshape.jcr.spi.index.IndexFeedback)`, and `removeIndex(org.modeshape.jcr.api.index.IndexDefinition, org.modeshape.jcr.spi.index.provider.ManagedIndex, java.lang.String)` methods for each index/workspace combination. Each of these methods can request via the `IndexFeedback` method parameter that all or parts of the repository content be scanned and re-indexed. (The repository does the scanning efficiently: if multiple providers request that the entire repository be scanned, the repository will index the content only once.) Also, each `ManagedIndex` resulting from these methods will be given its own even listener, and this is how the indexes are notified of changes in content (see below).
  6. If some content must be scanned, the repository will call `getIndexWriter()` and use the `IndexWriter` to notify the index(es) of the content.
  After the repository is running, calls to `IndexManager` will alter the `IndexDefinition`s index definitions. As these changes are persisted, the repository will call the `notify(IndexDefinitionChanges, ChangeBus, org.modeshape.jcr.NodeTypes.Supplier, Set, IndexFeedback)` again, this time with only the changes that were made to this provider's index definitions. If a new workspace is added or an existing workspace is removed, ModeShape will called `notify(WorkspaceChanges, ChangeBus, org.modeshape.jcr.NodeTypes.Supplier, Set, IndexFeedback)` with the relevant information to allow the provider to respond.

As sessions persist changes to content (via javax.jcr.Session#save() or by committing user transactions), the repository's event bus will notify each `ManagedIndex` (via its `writing adapter`) of these changes. This writing adapter is also used during manual re-indexing of content.

When queries are submitted, ModeShape will call `getIndexPlanner()` to obtain the planner that should determine for each portion of the query which indexes (if any) apply to that part of the query. When a particular index is to be used within a query, ModeShape will then call `getIndex(String,String)` and use it to answer the portion of the query.

## Custom providers

Implementing custom providers is fairly straightforward: simply extend this class, provide implementations for the abstract methods, and optionally override the default implementations for the other non-final methods.

- - ### Nested Class Summary

    Nested Classes
    Modifier and Type | Class and Description
    --- | ---
    `protected static interface` | `IndexProvider.ManagedIndexOperation` An operation that performs on a managed index with the associated index definition.

  - ### Constructor Summary

    Constructors
    Modifier | Constructor and Description
    --- | ---
    `protected` | `IndexProvider()`
    `protected` | `IndexProvider(IndexPlanner planner)`

  - ### Method Summary

    Methods
    Modifier and Type | Method and Description
    --- | ---
    `protected ExecutionContext` | `context()` Get the context in which this provider executes.
    `protected abstract ManagedIndex` | `createIndex(IndexDefinition defn, String workspaceName, NodeTypes.Supplier nodeTypesSupplier, ChangeSetAdapter.NodeTypePredicate matcher, IndexFeedback feedback)` Method called when this provider needs to create a new index given the unique pair of workspace name and index definition.
    `protected abstract void` | `doInitialize()` Method that should do the provider-specific initialization work.
    `Index` | `getIndex(String indexName, String workspaceName)` Get the queryable index with the given name and applicable for the given workspace.
    `protected Iterable<ManagedIndex>` | `getIndexes(String workspaceName)` Get this provider's `ProvidedIndex` instances for the given workspace.
    `IndexPlanner` | `getIndexPlanner()` Get the planner that, during the query planning/optimization phase, evaluates for a single source the AND-ed query constraints and defines indexes that may be used.
    `IndexWriter` | `getIndexWriter()` Get the writer that ModeShape can use to regenerate the indexes when a portion of the repository is to be re-indexed.
    `String` | `getName()` Get the name for this provider.
    `String` | `getRepositoryName()` Get the name of the repository.
    `void` | `initialize()` Initialize the provider.
    `protected Logger` | `logger()`
    `protected NameFactory` | `names()`
    `protected NamespaceRegistry` | `namespaces()` Get the namespace registry for the provider's `execution context`, and which can be used to convert qualified names (e.g., "`jcr:description`") to unqualified names (or vice versa).
    `void` | `notify(IndexDefinitionChanges changes, ChangeBus observable, NodeTypes.Supplier nodeTypesSupplier, Set<String> workspaceNames, IndexFeedback feedback)` Signal that some of the definitions of indexes owned by this provider were changed.
    `void` | `notify(NodeTypes updatedNodeTypes)` Notify the provider that the NodeTypes have changed.
    `void` | `notify(WorkspaceChanges changes, ChangeBus observable, NodeTypes.Supplier nodeTypesSupplier, Set<String> workspaceNames, IndexFeedback feedback)` Signal that some workspaces were added or removed.
    `protected void` | `onEachIndex(IndexProvider.ManagedIndexOperation op)` Perform the specified operation on each of the managed indexes.
    `protected void` | `onEachIndexInWorkspace(String workspaceName, IndexProvider.ManagedIndexOperation op)` Perform the specified operation on each of the managed indexes in the named workspace.
    `protected abstract void` | `planUseOfIndex(QueryContext context, IndexCostCalculator calculator, String workspaceName, ManagedIndex index, IndexDefinition defn)` The method that is called by the IndexProvider's `default IndexPlanner` for each managed index in the given workspace.
    `protected void` | `postShutdown()` Method called during #shutdown() after each of the managed indexes have been shutdown.
    `protected void` | `preShutdown()` Method called immediately when #shutdown() is invoked, before any other operations are performed and before the managed indexes are each shutdown.
    `protected abstract void` | `removeIndex(IndexDefinition oldDefn, ManagedIndex existingIndex, String workspaceName)` Method called when this provider needs to remove an existing index given the unique pair of workspace name and index definition.
    `void` | `shutdown()` Signal this provider that it is no longer needed and can release any resources that are being held.
    `protected abstract ManagedIndex` | `updateIndex(IndexDefinition oldDefn, IndexDefinition updatedDefn, ManagedIndex existingIndex, String workspaceName, NodeTypes.Supplier nodeTypesSupplier, ChangeSetAdapter.NodeTypePredicate matcher, IndexFeedback feedback)` Method called when this provider needs to update an existing index given the unique pair of workspace name and index definition.
    `abstract void` | `validateProposedIndex(ExecutionContext context, IndexDefinition defn, NodeTypes.Supplier nodeTypesSupplier, Problems problems)` Validate the proposed index definition, and use the supplied problems to report any issues that will prevent this provider from creating and using an index with the given definition.
    `protected ValueFactories` | `valueFactories()` Get the container for the type-specific factories useful to convert values that will be written to the index.

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

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

- - ### Constructor Detail

    - #### IndexProvider

          protected IndexProvider()

    - #### IndexProvider

          protected IndexProvider(IndexPlanner planner)

  - ### Method Detail

    - #### logger

          protected final Logger logger()

    - #### getName

          public final String getName()

      Get the name for this provider.
      Returns:
        the name; never null

    - #### getRepositoryName

          public final String getRepositoryName()

      Get the name of the repository.
      Returns:
        the repository name; never null

    - #### context

          protected final ExecutionContext context()

      Get the context in which this provider executes. This is set prior to `initialization` by ModeShape, and never changed.
      Returns:
        the execution context; never null

    - #### initialize

          public final void initialize()
                                throws RepositoryException

      Initialize the provider. This is called automatically by ModeShape once for each provider instance, and should not be called by the provider itself.
      Throws:
        `RepositoryException` - if there is a problem initializing the provider

    - #### doInitialize

          protected abstract void doInitialize()
                                        throws RepositoryException

      Method that should do the provider-specific initialization work. This is called by ModeShape once each time the repository is started; this method should not be called by the provider itself.

      By the time this method is called, ModeShape will hav already set the `context`, `logger`, `name`, and `repositoryName` plus any fields that match configuration properties for the provider.

      This is an excellent place for providers to validate the provider-specific fields set by ModeShape via reflection during instantiation.

      Throws:
        `RepositoryException` - if there is a problem initializing the provider

    - #### shutdown

          public final void shutdown()
                              throws RepositoryException

      Signal this provider that it is no longer needed and can release any resources that are being held.
      Throws:
        `RepositoryException` - if there is a problem shutting down the provider

    - #### preShutdown

          protected void preShutdown()
                              throws RepositoryException

      Method called immediately when #shutdown() is invoked, before any other operations are performed and before the managed indexes are each shutdown.
      Throws:
        `RepositoryException` - if there is a problem shutting down the provider

    - #### postShutdown

          protected void postShutdown()
                               throws RepositoryException

      Method called during #shutdown() after each of the managed indexes have been shutdown.
      Throws:
        `RepositoryException` - if there is a problem shutting down the provider

    - #### notify

          public void notify(NodeTypes updatedNodeTypes)

      Notify the provider that the NodeTypes have changed. This method should only be called by ModeShape and never called by other code.
      Parameters:
        `updatedNodeTypes` - the new node types; may not be null

    - #### validateProposedIndex

          public abstract void validateProposedIndex(ExecutionContext context,
                                   IndexDefinition defn,
                                   NodeTypes.Supplier nodeTypesSupplier,
                                   Problems problems)

      Validate the proposed index definition, and use the supplied problems to report any issues that will prevent this provider from creating and using an index with the given definition.
      Parameters:
        `context` - the execution context in which to perform the validation; never null
        `defn` - the proposed index definition; never null
        `nodeTypesSupplier` - the supplier for the NodeTypes object that contains information about the currently-registered node types; never null
        `problems` - the problems that should be used to report any issues with the index definition; never null

    - #### getIndexWriter

          public final IndexWriter getIndexWriter()

      Get the writer that ModeShape can use to regenerate the indexes when a portion of the repository is to be re-indexed.
      Returns:
        the index writer; may be null if the indexes are updated outside of ModeShape

    - #### getIndex

          public final Index getIndex(String indexName,
                       String workspaceName)

      Get the queryable index with the given name and applicable for the given workspace.
      Parameters:
        `indexName` - the name of the index in this provider; never null
        `workspaceName` - the name of the workspace; never null
      Returns:
        the queryable index, or null if there is no such index

    - #### getIndexes

          protected final Iterable<ManagedIndex> getIndexes(String workspaceName)

      Get this provider's `ProvidedIndex` instances for the given workspace.
      Parameters:
        `workspaceName` - the name of the workspace; may not be null
      Returns:
        the iterator over the provided indexes; never null but possibly empty

    - #### onEachIndex

          protected final void onEachIndex(IndexProvider.ManagedIndexOperation op)

      Perform the specified operation on each of the managed indexes.
      Parameters:
        `op` - the operation; may not be null

    - #### onEachIndexInWorkspace

          protected final void onEachIndexInWorkspace(String workspaceName,
                                    IndexProvider.ManagedIndexOperation op)

      Perform the specified operation on each of the managed indexes in the named workspace.
      Parameters:
        `workspaceName` - the name of the workspace; may not be null
        `op` - the operation; may not be null

    - #### planUseOfIndex

          protected abstract void planUseOfIndex(QueryContext context,
                            IndexCostCalculator calculator,
                            String workspaceName,
                            ManagedIndex index,
                            IndexDefinition defn)

      The method that is called by the IndexProvider's `default IndexPlanner` for each managed index in the given workspace.

      Subclasses should implement this method to determine and record whether the supplied index can be used by the query against the named workspace.

      The `IndexUsage` class may be useful to determine for a given index definition whether criteria is applicable.

      Parameters:
        `context` - the context of the original query; never null
        `calculator` - the calculator that should be used to record plan information for the index; never null
        `workspaceName` - the name of the workspace against which the query is operating; never null
        `index` - the managed index in the given workspace; never null
        `defn` - the definition for the index; never null

    - #### getIndexPlanner

          public final IndexPlanner getIndexPlanner()

      Get the planner that, during the query planning/optimization phase, evaluates for a single source the AND-ed query constraints and defines indexes that may be used.

      This method is typically called only once after the provider has been `initialized`.

      Returns:
        the index planner; may not be null

    - #### namespaces

          protected final NamespaceRegistry namespaces()

      Get the namespace registry for the provider's `execution context`, and which can be used to convert qualified names (e.g., "`jcr:description`") to unqualified names (or vice versa).
      Returns:
        the namespace registry; never null

    - #### valueFactories

          protected final ValueFactories valueFactories()

      Get the container for the type-specific factories useful to convert values that will be written to the index.
      Returns:
        the container of type-specific value factories; never null

    - #### names

          protected final NameFactory names()

    - #### notify

          public final void notify(WorkspaceChanges changes,
                    ChangeBus observable,
                    NodeTypes.Supplier nodeTypesSupplier,
                    Set<String> workspaceNames,
                    IndexFeedback feedback)

      Signal that some workspaces were added or removed. This method is also called upon startup of this repository instance so that the provider understands the index definitions that are available. The provider should adapt to these changes as best as possible.

      This method examines the supplied `workspace additions and removals`, and updates the internal state of this provider. It will then call the `createIndex(org.modeshape.jcr.api.index.IndexDefinition, java.lang.String, org.modeshape.jcr.NodeTypes.Supplier, org.modeshape.jcr.cache.change.ChangeSetAdapter.NodeTypePredicate, org.modeshape.jcr.spi.index.IndexFeedback)`, `updateIndex(org.modeshape.jcr.api.index.IndexDefinition, org.modeshape.jcr.api.index.IndexDefinition, org.modeshape.jcr.spi.index.provider.ManagedIndex, java.lang.String, org.modeshape.jcr.NodeTypes.Supplier, org.modeshape.jcr.cache.change.ChangeSetAdapter.NodeTypePredicate, org.modeshape.jcr.spi.index.IndexFeedback)`, or `removeIndex(org.modeshape.jcr.api.index.IndexDefinition, org.modeshape.jcr.spi.index.provider.ManagedIndex, java.lang.String)` methods for each of the affected indexes.

      Parameters:
        `changes` - the changes in the workspaces; never null
        `observable` - the Observable object with which an index can register a listener for changes; this is the only mechanism by which the indexes can be updated
        `nodeTypesSupplier` - the supplier from which can be very efficiently obtained the latest `snapshot of node types` useful in determining if changes on a node are to be included in an index of a particular `index node type`.
        `workspaceNames` - the names of all workspaces in this repository; never null and likely never null
        `feedback` - the feedback mechanism for this provider to signal to ModeShape that one or more indexes need to be entirely or partially rebuilt via scanning; never null

    - #### notify

          public final void notify(IndexDefinitionChanges changes,
                    ChangeBus observable,
                    NodeTypes.Supplier nodeTypesSupplier,
                    Set<String> workspaceNames,
                    IndexFeedback feedback)

      Signal that some of the definitions of indexes owned by this provider were changed. This method is also called upon startup of this repository instance so that the provider understands the index definitions that are available. The provider should adapt to these changes as best as possible.

      This method examines the supplied `changes`, current workspaces, and maintains the internal state of this provider. It will then call the `createIndex(org.modeshape.jcr.api.index.IndexDefinition, java.lang.String, org.modeshape.jcr.NodeTypes.Supplier, org.modeshape.jcr.cache.change.ChangeSetAdapter.NodeTypePredicate, org.modeshape.jcr.spi.index.IndexFeedback)`, `updateIndex(org.modeshape.jcr.api.index.IndexDefinition, org.modeshape.jcr.api.index.IndexDefinition, org.modeshape.jcr.spi.index.provider.ManagedIndex, java.lang.String, org.modeshape.jcr.NodeTypes.Supplier, org.modeshape.jcr.cache.change.ChangeSetAdapter.NodeTypePredicate, org.modeshape.jcr.spi.index.IndexFeedback)`, or `removeIndex(org.modeshape.jcr.api.index.IndexDefinition, org.modeshape.jcr.spi.index.provider.ManagedIndex, java.lang.String)` methods for each of the affected indexes.

      Parameters:
        `changes` - the changes in the definitions; never null
        `observable` - the Observable object with which an index can register a listener for changes; this is the only mechanism by which the indexes can be updated
        `nodeTypesSupplier` - the supplier from which can be very efficiently obtained the latest `snapshot of node types` useful in determining if changes on a node are to be included in an index of a particular `index node type`.
        `workspaceNames` - the names of all workspaces in this repository; never null and likely never null
        `feedback` - the feedback mechanism for this provider to signal to ModeShape that one or more indexes need to be entirely or partially rebuilt via scanning; never null

    - #### createIndex

          protected abstract ManagedIndex createIndex(IndexDefinition defn,
                                 String workspaceName,
                                 NodeTypes.Supplier nodeTypesSupplier,
                                 ChangeSetAdapter.NodeTypePredicate matcher,
                                 IndexFeedback feedback)

      Method called when this provider needs to create a new index given the unique pair of workspace name and index definition. An index definition can apply to multiple workspaces, and when it does this method will be called once for each applicable workspace.
      Parameters:
        `defn` - the definition of the index; never null
        `workspaceName` - the name of the actual workspace to which the new index applies; never null
        `nodeTypesSupplier` - the supplier for the current node types cache; never null
        `matcher` - the node type matcher used to determine which nodes should be included in the index, and which automatically updates when node types are changed in the repository; may not be null
        `feedback` - the feedback mechanism for this provider to signal to ModeShape that portions of the repository content must be scanned to build/populate the new index; never null
      Returns:
        the implementation-specific `ManagedIndex` for the new index; may not be null

    - #### updateIndex

          protected abstract ManagedIndex updateIndex(IndexDefinition oldDefn,
                                 IndexDefinition updatedDefn,
                                 ManagedIndex existingIndex,
                                 String workspaceName,
                                 NodeTypes.Supplier nodeTypesSupplier,
                                 ChangeSetAdapter.NodeTypePredicate matcher,
                                 IndexFeedback feedback)

      Method called when this provider needs to update an existing index given the unique pair of workspace name and index definition. An index definition can apply to multiple workspaces, and when it is changed this method will be called once for each applicable workspace.
      Parameters:
        `oldDefn` - the previous definition of the index; never null
        `updatedDefn` - the updated definition of the index; never null
        `existingIndex` - the existing index prior to this update, as returned from `createIndex(org.modeshape.jcr.api.index.IndexDefinition, java.lang.String, org.modeshape.jcr.NodeTypes.Supplier, org.modeshape.jcr.cache.change.ChangeSetAdapter.NodeTypePredicate, org.modeshape.jcr.spi.index.IndexFeedback)` or `updateIndex(org.modeshape.jcr.api.index.IndexDefinition, org.modeshape.jcr.api.index.IndexDefinition, org.modeshape.jcr.spi.index.provider.ManagedIndex, java.lang.String, org.modeshape.jcr.NodeTypes.Supplier, org.modeshape.jcr.cache.change.ChangeSetAdapter.NodeTypePredicate, org.modeshape.jcr.spi.index.IndexFeedback)` ; never null
        `workspaceName` - the name of the actual workspace to which the new index applies; never null
        `nodeTypesSupplier` - the supplier for the current node types cache; never null
        `matcher` - the node type matcher used to determine which nodes should be included in the index, and which automatically updates when node types are changed in the repository; may not be null
        `feedback` - the feedback mechanism for this provider to signal to ModeShape that portions of the repository content must be scanned to rebuild/repopulate the updated index; never null
      Returns:
        the operations and provider-specific state for this index; never null

    - #### removeIndex

          protected abstract void removeIndex(IndexDefinition oldDefn,
                         ManagedIndex existingIndex,
                         String workspaceName)

      Method called when this provider needs to remove an existing index given the unique pair of workspace name and index definition. An index definition can apply to multiple workspaces, and when it does this method will be called once for each applicable workspace.
      Parameters:
        `oldDefn` - the previous definition of the index; never null
        `existingIndex` - the existing index prior to this update, as returned from `createIndex(org.modeshape.jcr.api.index.IndexDefinition, java.lang.String, org.modeshape.jcr.NodeTypes.Supplier, org.modeshape.jcr.cache.change.ChangeSetAdapter.NodeTypePredicate, org.modeshape.jcr.spi.index.IndexFeedback)` or `updateIndex(org.modeshape.jcr.api.index.IndexDefinition, org.modeshape.jcr.api.index.IndexDefinition, org.modeshape.jcr.spi.index.provider.ManagedIndex, java.lang.String, org.modeshape.jcr.NodeTypes.Supplier, org.modeshape.jcr.cache.change.ChangeSetAdapter.NodeTypePredicate, org.modeshape.jcr.spi.index.IndexFeedback)` ; never null
        `workspaceName` - the name of the actual workspace to which the new index applies; never null

Copyright © 2008-2014 JBoss, a division of Red Hat. All Rights Reserved.