in src/main/java/org/apache/sling/resourceresolver/impl/observation/BasicObservationReporter.java [86:177]
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);
}