// Then for each provider ...
for (Map.Entry<String, List<IndexDefinition>> entry : defnsByProvider.entrySet()) {
String providerName = entry.getKey();
WorkspaceIndexChanges changes = new WorkspaceIndexChanges(entry.getValue(), addedWorkspaces,
removedWorkspaces);
IndexProvider provider = providers.get(providerName);
if (provider == null) continue;
provider.notify(changes, repository.changeBus(), repository.nodeTypeManager(),
repository.repositoryCache().getWorkspaceNames(), feedback.forProvider(providerName));
}
}
}
return feedback;
}
if (!systemWorkspaceName.equals(changeSet.getWorkspaceName())) {
// The change does not affect the 'system' workspace, so skip it ...
return null;
}
// It is simple to listen to all local and remote changes. Therefore, any changes made locally to the index definitions
// will be propagated through the cached representation via this listener.
AtomicReference<Map<Name, IndexChangeInfo>> changesByProviderName = new AtomicReference<>();
for (Change change : changeSet) {
if (change instanceof NodeAdded) {
NodeAdded added = (NodeAdded)change;
Path addedPath = added.getPath();
if (indexesPath.isAncestorOf(addedPath)) {
// Get the name of the affected provider ...
Name providerName = addedPath.getSegment(2).getName();
if (addedPath.size() > 3) {
// Adding an index (or column definition), but all we care about is the name of the index
Name indexName = addedPath.getSegment(3).getName();
changeInfoForProvider(changesByProviderName, providerName).changed(indexName);
}
}
} else if (change instanceof NodeRemoved) {
NodeRemoved removed = (NodeRemoved)change;
Path removedPath = removed.getPath();
if (indexesPath.isAncestorOf(removedPath)) {
// Get the name of the affected provider ...
Name providerName = removedPath.getSegment(2).getName();
if (removedPath.size() > 4) {
// It's a column definition being removed, so the index is changed ...
Name indexName = removedPath.getSegment(3).getName();
changeInfoForProvider(changesByProviderName, providerName).removed(indexName);
} else if (removedPath.size() > 3) {
// Removing an index (or column definition), but all we care about is the name of the index
Name indexName = removedPath.getSegment(3).getName();
changeInfoForProvider(changesByProviderName, providerName).removed(indexName);
} else if (removedPath.size() == 3) {
// The whole provider was removed ...
changeInfoForProvider(changesByProviderName, providerName).removedAll();
}
}
} else if (change instanceof PropertyChanged) {
PropertyChanged propChanged = (PropertyChanged)change;
Path changedPath = propChanged.getPathToNode();
if (indexesPath.isAncestorOf(changedPath)) {
if (changedPath.size() > 3) {
// Adding an index (or column definition), but all we care about is the name of the index
Name providerName = changedPath.getSegment(2).getName();
Name indexName = changedPath.getSegment(3).getName();
changeInfoForProvider(changesByProviderName, providerName).changed(indexName);
}
}
} // we don't care about node moves (don't happen) or property added/removed (handled by node add/remove)
}
if (changesByProviderName.get() == null || changesByProviderName.get().isEmpty()) {
// No changes to the indexes ...
return null;
}
// Refresh the index definitions ...
RepositoryIndexes indexes = readIndexDefinitions();
// And notify the affected providers ...
StringFactory strings = context.getValueFactories().getStringFactory();
ScanningTasks feedback = new ScanningTasks();
for (Map.Entry<Name, IndexChangeInfo> entry : changesByProviderName.get().entrySet()) {
String providerName = strings.create(entry.getKey());
IndexProvider provider = providers.get(providerName);
if (provider == null) continue;
IndexChanges changes = new IndexChanges();
IndexChangeInfo info = entry.getValue();
if (info.removedAll) {
// Get all of the definitions for this provider ...
for (IndexDefinition defn : indexes.getIndexDefinitions().values()) {
if (defn.getProviderName().equals(providerName)) changes.remove(defn.getName());
}
}
// Others might have been added or changed after the existing ones were removed ...
for (Name name : info.removedIndexes) {
changes.remove(strings.create(name));
}
for (Name name : info.changedIndexes) {
IndexDefinition defn = indexes.getIndexDefinitions().get(strings.create(name));
if (defn != null) changes.change(defn);
}
// Notify the provider ...
try {
provider.notify(changes, repository.changeBus(), repository.nodeTypeManager(), repository.repositoryCache()
.getWorkspaceNames(),
feedback.forProvider(providerName));
} catch (RuntimeException e) {
logger.error(e, JcrI18n.errorNotifyingProviderOfIndexChanges, providerName, repository.name(), e.getMessage());
}