/** * Add default exclusions to the current exclusions set. */ @Override public synchronized void addDefaultExcludes() { Stream<String> s = Stream.of(getDefaultExcludes()).map(p -> p.replace('/', File.separatorChar).replace('\\', File.separatorChar)); if (excludes != null) { s = Stream.concat(Stream.of(excludes), s); } excludes = s.toArray(String[]::new); }
/** * Lists recursive files of this directory with pattern matching. * <p>The default implementation calls {@link #list()} recursively inside {@link #run} and applies filtering to the result. * Implementations may wish to override this more efficiently. * @param includes comma-separated Ant-style globs as per {@link Util#createFileSet(File, String, String)} using {@code /} as a path separator; * the empty string means <em>no matches</em> (use {@link SelectorUtils#DEEP_TREE_MATCH} if you want to match everything except some excludes) * @param excludes optional excludes in similar format to {@code includes} * @param useDefaultExcludes as per {@link AbstractFileSet#setDefaultexcludes} * @return a list of {@code /}-separated relative names of children (files directly inside or in subdirectories) * @throws IOException if this is not a directory, or listing was not possible for some other reason * @since 2.118 */ @Restricted(Beta.class) public @Nonnull Collection<String> list(@Nonnull String includes, @CheckForNull String excludes, boolean useDefaultExcludes) throws IOException { Collection<String> r = run(new CollectFiles(this)); List<TokenizedPattern> includePatterns = patterns(includes); List<TokenizedPattern> excludePatterns = patterns(excludes); if (useDefaultExcludes) { for (String patt : DirectoryScanner.getDefaultExcludes()) { excludePatterns.add(new TokenizedPattern(patt.replace('/', File.separatorChar))); } } return r.stream().filter(p -> { TokenizedPath path = new TokenizedPath(p.replace('/', File.separatorChar)); return includePatterns.stream().anyMatch(patt -> patt.matchPath(path, true)) && !excludePatterns.stream().anyMatch(patt -> patt.matchPath(path, true)); }).collect(Collectors.toSet()); } private static final class CollectFiles extends MasterToSlaveCallable<Collection<String>, IOException> {
/** * Does the work. * * @exception BuildException if something goes wrong with the build */ @Override public void execute() throws BuildException { if (!defaultrequested && add.isEmpty() && remove.isEmpty() && !echo) { throw new BuildException( "<defaultexcludes> task must set at least one attribute (echo=\"false\" doesn't count since that is the default"); } if (defaultrequested) { DirectoryScanner.resetDefaultExcludes(); } if (!add.isEmpty()) { DirectoryScanner.addDefaultExclude(add); } if (!remove.isEmpty()) { DirectoryScanner.removeDefaultExclude(remove); } if (echo) { String message = Arrays.stream(DirectoryScanner.getDefaultExcludes()) .map(exclude -> String.format(" %s%n", exclude)) .collect(Collectors.joining("", "Current Default Excludes:%n", "")); log(message, logLevel); } }
@Test public void testWindowsPathMatching() { final Set<String> dataFileIncludes = ImmutableSet.of("**\\*.xml"); final Set<String> dataFileExcludes = ImmutableSet.copyOf(DirectoryScanner.getDefaultExcludes()); final AntPatternFileFilter antPatternFileFilter = new AntPatternFileFilter(false, true, dataFileIncludes, dataFileExcludes); final boolean accepted = antPatternFileFilter.accept( null, "C:\\up\\uPortal_trunk\\uportal-war\\src\\main\\data\\default_entities\\portlet\\ImportExportPortlet.portlet.xml"); assertTrue(accepted); }
@Ignore @Test public void testExactNameMatching() { final Set<String> dataFileIncludes = ImmutableSet.of("youtube.portlet.xml", "**/test.xml", "te?.xml", "te*.xml"); final Set<String> dataFileExcludes = ImmutableSet.copyOf(DirectoryScanner.getDefaultExcludes()); final AntPatternFileFilter antPatternFileFilter = new AntPatternFileFilter(false, true, dataFileIncludes, dataFileExcludes); final boolean accepted = antPatternFileFilter.accept( null, "/uportal-war/src/main/data/default_entities/portlet/youtube.portlet.xml"); assertTrue(accepted); } }