Search in sources :

Example 1 with Selector

use of org.apache.jackrabbit.oak.plugins.observation.filter.UniversalFilter.Selector in project jackrabbit-oak by apache.

the class SelectorTest method selectDescendant.

@Test
public void selectDescendant() {
    Selector selector = new RelativePathSelector("/a/b/c", Selectors.PARENT);
    UniversalFilter filter = new UniversalFilter(root, root, selector, ALL);
    assertEquals(nodeC, selector.select(filter, null, null));
}
Also used : Selector(org.apache.jackrabbit.oak.plugins.observation.filter.UniversalFilter.Selector) Test(org.junit.Test)

Example 2 with Selector

use of org.apache.jackrabbit.oak.plugins.observation.filter.UniversalFilter.Selector 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());
}
Also used : Condition(org.apache.jackrabbit.oak.plugins.observation.filter.FilterBuilder.Condition) ExcludeExternal(org.apache.jackrabbit.oak.plugins.observation.ExcludeExternal) ChangeSetFilterImpl(org.apache.jackrabbit.oak.plugins.observation.filter.ChangeSetFilterImpl) FilterBuilder(org.apache.jackrabbit.oak.plugins.observation.filter.FilterBuilder) ListenerTracker(org.apache.jackrabbit.commons.observation.ListenerTracker) Selector(org.apache.jackrabbit.oak.plugins.observation.filter.UniversalFilter.Selector)

Aggregations

Selector (org.apache.jackrabbit.oak.plugins.observation.filter.UniversalFilter.Selector)2 ListenerTracker (org.apache.jackrabbit.commons.observation.ListenerTracker)1 ExcludeExternal (org.apache.jackrabbit.oak.plugins.observation.ExcludeExternal)1 ChangeSetFilterImpl (org.apache.jackrabbit.oak.plugins.observation.filter.ChangeSetFilterImpl)1 FilterBuilder (org.apache.jackrabbit.oak.plugins.observation.filter.FilterBuilder)1 Condition (org.apache.jackrabbit.oak.plugins.observation.filter.FilterBuilder.Condition)1 Test (org.junit.Test)1