AdvancedFilterValidator implements GenericMetaInfDataValidator, FilterValidator, DocumentViewXmlValidator, JcrPathValidator { @Nullable String getDanglingAncestorNodePath(String nodePath, WorkspaceFilter filter) { if (danglingNodePaths.contains(nodePath)) { return null; } for (PathFilterSet pathFilterSet : filter.getFilterSets()) { if (pathFilterSet.contains(nodePath)) { String parentNodePath = Text.getRelativeParent(nodePath, 1); if (!nodePath.equals(pathFilterSet.getRoot()) && !parentNodePath.equals(pathFilterSet.getRoot())) { return getDanglingAncestorNodePath(parentNodePath, filter); } else { return null; } } } danglingNodePaths.add(nodePath); return nodePath; } AdvancedFilterValidator(@NotNull DocumentBuilderFactory factory, @NotNull ValidationMessageSeverity defaultSeverity, @NotNull ValidationMessageSeverity severityForUncoveredAncestorNodes, @NotNull ValidationMessageSeverity severityForUncoveredFilterRootAncestors, @NotNull ValidationMessageSeverity severityForOrphanedFilterEntries, boolean isSubPackage, @NotNull Collection<PackageInfo> dependenciesMetaInfo, @NotNull WorkspaceFilter filter, @NotNull Collection<String> validRoots); void setFilterValidators(Map<String, FilterValidator> filterValidators); @Override Collection<ValidationMessage> done(); @Override Collection<ValidationMessage> validate(@NotNull WorkspaceFilter filter); @Override @Nullable Collection<ValidationMessage> validateJcrPath(@NotNull NodeContext nodeContext,
            boolean isFolder); @Override @Nullable Collection<ValidationMessage> validate(@NotNull DocViewNode node, @NotNull NodeContext nodeContext,
            boolean isRoot); @Override Collection<ValidationMessage> validateMetaInfData(@NotNull InputStream input, @NotNull Path filePath, @NotNull Path basePath); @Override boolean shouldValidateMetaInfData(@NotNull Path filePath);  }
@Test public void testHasDanglingAncestors() throws IOException, ConfigurationException { DefaultWorkspaceFilter filter = new DefaultWorkspaceFilter(); try (InputStream input = this.getClass().getResourceAsStream("/test-filter.xml")) { filter.load(input); } validator = new AdvancedFilterValidator( factory, ValidationMessageSeverity.WARN, AdvancedFilterValidatorFactory.DEFAULT_SEVERITY_FOR_UNCOVERED_ANCESTOR_NODES, ValidationMessageSeverity.ERROR, ValidationMessageSeverity.ERROR, false, dependenciesMetaInfo, filter, validRoots); Assert.assertNull(validator.getDanglingAncestorNodePath("/var/acs-commons/on-deploy-scripts-status/README.txt", filter)); Assert.assertEquals("/var/acs-commons/mcp", validator.getDanglingAncestorNodePath("/var/acs-commons/mcp/rep:policy", filter)); Assert.assertNull(validator.getDanglingAncestorNodePath("/var/acs-commons/on-deploy-scripts-status/rep:policy", filter)); Assert.assertNull(validator.getDanglingAncestorNodePath("/var/acs-commons/mcp/rep:policy/allow", filter)); }