use of org.apache.jackrabbit.oak.plugins.observation.ExcludeExternal in project jackrabbit-oak by apache.
the class ObservationManagerImpl method addEventListener.
@Override
public void addEventListener(EventListener listener, int eventTypes, String absPath, boolean isDeep, String[] uuids, String[] nodeTypeName, boolean noLocal) throws RepositoryException {
JackrabbitEventFilter filter = new JackrabbitEventFilter();
filter.setEventTypes(eventTypes);
if (absPath != null) {
filter.setAbsPath(absPath);
}
filter.setIsDeep(isDeep);
if (uuids != null) {
filter.setIdentifiers(uuids);
}
if (nodeTypeName != null) {
filter.setNodeTypes(nodeTypeName);
}
filter.setNoLocal(noLocal);
filter.setNoExternal(listener instanceof ExcludeExternal);
addEventListener(listener, filter);
}
use of org.apache.jackrabbit.oak.plugins.observation.ExcludeExternal 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