in src/main/java/org/apache/sling/resourceresolver/impl/observation/BasicObservationReporter.java [84:179]
public BasicObservationReporter(
final List<String> searchPath,
final Collection<ResourceChangeListenerInfo> infos,
final Path providerPath,
final PathSet excludePaths) {
this.searchPath = searchPath;
final List<ObserverConfiguration> observerConfigs = new ArrayList<>();
for (final ResourceChangeListenerInfo info : infos) {
if (!info.getResourceChangeTypes().isEmpty()) {
// find the set of paths that match the provider
final Set<Path> paths = new HashSet<>();
for (final Path p : info.getPaths()) {
// add when there is an intersection between provider path and resource change listener path
boolean add =
providerPath.matches(p.getPath()) || (!p.isPattern() && p.matches(providerPath.getPath()));
if (add) {
if (p.isPattern()) {
for (final Path exclude : excludePaths) {
if (p.getPath().startsWith(Path.GLOB_PREFIX + exclude.getPath() + "/")) {
logger.debug("ResourceChangeListener {} is shadowed by {}", info, exclude);
add = false;
break;
}
}
} else {
final Path exclude = excludePaths.matches(p.getPath());
if (exclude != null) {
logger.debug("ResourceChangeListener {} is shadowed by {}", info, exclude);
add = false;
}
}
}
if (add) {
paths.add(p);
}
}
if (!paths.isEmpty()) {
final PathSet pathSet = PathSet.fromPathCollection(paths);
// search for an existing configuration with the same paths and hints
BasicObserverConfiguration found = null;
for (final ObserverConfiguration c : observerConfigs) {
if (c.getPaths().equals(pathSet)
&& ((c.getPropertyNamesHint() == null && info.getPropertyNamesHint() == null)
|| c.getPropertyNamesHint() != null
&& c.getPropertyNamesHint().equals(info.getPropertyNamesHint()))) {
found = (BasicObserverConfiguration) c;
break;
}
}
final BasicObserverConfiguration config;
if (found != null) {
// check external and types
boolean createNew = false;
if (!found.includeExternal() && info.isExternal()) {
createNew = true;
}
if (!found.getChangeTypes().equals(info.getResourceChangeTypes())) {
createNew = true;
}
if (createNew) {
// create new/updated config
observerConfigs.remove(found);
final Set<ResourceChange.ChangeType> types = new HashSet<>();
types.addAll(found.getChangeTypes());
types.addAll(info.getResourceChangeTypes());
config = new BasicObserverConfiguration(
pathSet,
types,
info.isExternal() || found.includeExternal(),
found.getExcludedPaths(),
found.getPropertyNamesHint());
observerConfigs.add(config);
for (final ResourceChangeListenerInfo i : found.getListeners()) {
config.addListener(i);
}
} else {
config = found;
}
} else {
// create new config
config = new BasicObserverConfiguration(
pathSet,
info.getResourceChangeTypes(),
info.isExternal(),
excludePaths.getSubset(pathSet),
info.getPropertyNamesHint());
observerConfigs.add(config);
}
config.addListener(info);
}
}
}
this.configs = Collections.unmodifiableList(observerConfigs);
}