use of org.apache.jackrabbit.commons.observation.ListenerTracker in project jackrabbit-oak by apache.
the class ObservationManagerImpl method addEventListener.
/**
* Adds an event listener that listens for the events specified
* by the {@code filterProvider} passed to this method.
* <p>
* The set of events will be further filtered by the access rights
* of the current {@code Session}.
* <p>
* The filters of an already-registered {@code EventListener} can be
* changed at runtime by re-registering the same {@code EventListener}
* object (i.e. the same actual Java object) with a new filter provider.
* The implementation must ensure that no events are lost during the
* changeover.
*
* @param listener an {@link EventListener} object.
* @param filterProvider filter provider specifying the filter for this listener
*/
public void addEventListener(EventListener listener, FilterProvider filterProvider) {
// FIXME Add support for FilterProvider in ListenerTracker
ListenerTracker tracker = new WarningListenerTracker(true, listener, 0, null, true, null, null, false);
addEventListener(listener, tracker, filterProvider);
}
use of org.apache.jackrabbit.commons.observation.ListenerTracker in project jackrabbit-oak by apache.
the class ObservationManagerImpl method addEventListener.
@Override
public void addEventListener(EventListener listener, JackrabbitEventFilter filter) throws RepositoryException {
OakEventFilterImpl oakEventFilter = null;
if (filter instanceof OakEventFilterImpl) {
oakEventFilter = (OakEventFilterImpl) filter;
}
int eventTypes = filter.getEventTypes();
boolean isDeep = filter.getIsDeep();
String[] uuids = filter.getIdentifiers();
String[] nodeTypeName = filter.getNodeTypes();
boolean noLocal = filter.getNoLocal();
boolean noExternal = filter.getNoExternal() || listener instanceof ExcludeExternal;
boolean noInternal = filter.getNoInternal();
Set<String> includePaths = getOakPaths(namePathMapper, filter.getAdditionalPaths());
String absPath = filter.getAbsPath();
if (absPath != null) {
includePaths.add(namePathMapper.getOakPath(absPath));
}
Set<String> excludedPaths = getOakPaths(namePathMapper, filter.getExcludedPaths());
PathUtils.unifyInExcludes(includePaths, excludedPaths);
if (oakEventFilter != null) {
String[] includeGlobPaths = oakEventFilter.getIncludeGlobPaths();
if (includeGlobPaths != null) {
includePaths.addAll(Arrays.asList(includeGlobPaths));
}
}
if (includePaths.isEmpty()) {
LOG.warn("The passed filter excludes all events. No event listener registered");
return;
}
FilterBuilder filterBuilder = new FilterBuilder();
String depthPattern = isDeep ? STAR + '/' + STAR_STAR : STAR;
List<Condition> includeConditions = newArrayList();
filterBuilder.addPathsForMBean(includePaths);
for (String path : includePaths) {
final String deepenedPath;
if (path.endsWith(STAR)) {
// that's the case for a glob ending with * already, so
// no need to add another * or **
deepenedPath = path;
} else if (path.contains(STAR)) {
// for any other glob path that doesn't end with *
// we only add a single *, not a **
deepenedPath = concat(path, STAR);
} else {
// for any non-glob path we do it the traditional way
deepenedPath = concat(path, depthPattern);
}
includeConditions.add(filterBuilder.path(deepenedPath));
if (oakEventFilter != null && oakEventFilter.getIncludeAncestorsRemove()) {
// the subtree here as a result.
continue;
}
// only register the part leading to the first STAR:
filterBuilder.addSubTree(pathWithoutGlob(path));
}
List<Condition> excludeConditions = createExclusions(filterBuilder, excludedPaths);
final String[] validatedNodeTypeNames = validateNodeTypeNames(nodeTypeName);
Selector nodeTypeSelector = Selectors.PARENT;
boolean deleteSubtree = true;
if (oakEventFilter != null) {
Condition additionalIncludes = oakEventFilter.getAdditionalIncludeConditions(includePaths);
if (additionalIncludes != null) {
includeConditions.add(additionalIncludes);
}
filterBuilder.aggregator(oakEventFilter.getAggregator());
if (oakEventFilter.getApplyNodeTypeOnSelf()) {
nodeTypeSelector = Selectors.THIS;
}
if (oakEventFilter.getIncludeSubtreeOnRemove()) {
deleteSubtree = false;
}
}
if (deleteSubtree) {
excludeConditions.add(filterBuilder.deleteSubtree());
}
Condition condition = filterBuilder.all(filterBuilder.all(excludeConditions), filterBuilder.any(includeConditions), // filterBuilder.deleteSubtree(), // moved depending on deleteSubtree on excludeConditions
filterBuilder.moveSubtree(), filterBuilder.eventType(eventTypes), filterBuilder.uuid(Selectors.PARENT, uuids), filterBuilder.nodeType(nodeTypeSelector, validatedNodeTypeNames), filterBuilder.accessControl(permissionProviderFactory));
if (oakEventFilter != null) {
condition = oakEventFilter.wrapMainCondition(condition, filterBuilder, permissionProviderFactory);
}
filterBuilder.includeSessionLocal(!noLocal).includeClusterExternal(!noExternal).includeClusterLocal(!noInternal).condition(condition);
// FIXME support multiple path in ListenerTracker
ListenerTracker tracker = new WarningListenerTracker(!noExternal, listener, eventTypes, absPath, isDeep, uuids, nodeTypeName, noLocal);
Set<String> additionalIncludePaths = null;
if (oakEventFilter != null) {
additionalIncludePaths = oakEventFilter.calcPrefilterIncludePaths(includePaths);
}
// OAK-5082 : node type filtering should not only be direct but include derived types
// one easy way to solve this is to 'explode' the node types at start by including
// all subtypes of every registered node type
HashSet<String> explodedNodeTypes = null;
if (validatedNodeTypeNames != null) {
explodedNodeTypes = newHashSet();
for (String nt : validatedNodeTypeNames) {
explodeSubtypes(nt, explodedNodeTypes);
}
}
// OAK-4908 : prefiltering support. here we have explicit yes/no/maybe filtering
// for things like propertyNames/nodeTypes/nodeNames/paths which cannot be
// applied on the full-fledged filterBuilder above but requires an explicit 'prefilter' for that.
filterBuilder.setChangeSetFilter(new ChangeSetFilterImpl(includePaths, isDeep, additionalIncludePaths, excludedPaths, null, explodedNodeTypes, null));
addEventListener(listener, tracker, filterBuilder.build());
}
Aggregations