Bug 1270213 - Move generic file filters to FileUtil. r=sebastian
These will be used by the Store in the upcoming patches.
MozReview-Commit-ID: 7sPICagdLMu
--- a/mobile/android/base/java/org/mozilla/gecko/util/FileUtils.java
+++ b/mobile/android/base/java/org/mozilla/gecko/util/FileUtils.java
@@ -12,16 +12,19 @@ import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.FilenameFilter;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.nio.charset.Charset;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import org.json.JSONException;
import org.json.JSONObject;
import org.mozilla.gecko.annotation.RobocopTarget;
public class FileUtils {
private static final String LOGTAG = "GeckoFileUtils";
@@ -195,9 +198,45 @@ public class FileUtils {
writer.close();
}
} finally {
// OutputStreamWriter.close can throw before closing the
// underlying stream. For safety, we close here too.
outputStream.close();
}
}
+
+ public static class FilenameWhitelistFilter implements FilenameFilter {
+ private final Set<String> mFilenameWhitelist;
+
+ public FilenameWhitelistFilter(final Set<String> filenameWhitelist) {
+ mFilenameWhitelist = filenameWhitelist;
+ }
+
+ @Override
+ public boolean accept(final File dir, final String filename) {
+ return mFilenameWhitelist.contains(filename);
+ }
+ }
+
+ public static class FilenameRegexFilter implements FilenameFilter {
+ private final Pattern mPattern;
+
+ // Each time `Pattern.matcher` is called, a new matcher is created. We can avoid the excessive object creation
+ // by caching the returned matcher and calling `Matcher.reset` on it. Since Matcher's are not thread safe,
+ // this assumes `FilenameFilter.accept` is not run in parallel (which, according to the source, it is not).
+ private Matcher mCachedMatcher;
+
+ public FilenameRegexFilter(final Pattern pattern) {
+ mPattern = pattern;
+ }
+
+ @Override
+ public boolean accept(final File dir, final String filename) {
+ if (mCachedMatcher == null) {
+ mCachedMatcher = mPattern.matcher(filename);
+ } else {
+ mCachedMatcher.reset(filename);
+ }
+ return mCachedMatcher.matches();
+ }
+ }
}
--- a/mobile/android/tests/background/junit4/src/org/mozilla/gecko/util/TestFileUtils.java
+++ b/mobile/android/tests/background/junit4/src/org/mozilla/gecko/util/TestFileUtils.java
@@ -9,25 +9,31 @@ package org.mozilla.gecko.util;
import org.json.JSONException;
import org.json.JSONObject;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith;
import org.mozilla.gecko.background.testhelpers.TestRunner;
+import org.mozilla.gecko.util.FileUtils.FilenameRegexFilter;
+import org.mozilla.gecko.util.FileUtils.FilenameWhitelistFilter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.nio.charset.Charset;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.regex.Pattern;
import static junit.framework.Assert.*;
import static org.mockito.Mockito.*;
/**
* Tests the utilities in {@link FileUtils}.
*/
@RunWith(TestRunner.class)
@@ -279,9 +285,39 @@ public class TestFileUtils {
// Since the write methods may not be tested yet.
private static void writeStringToFile(final File file, final String str) throws IOException {
try (OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(file, false), CHARSET)) {
writer.write(str);
}
assertTrue("Written file from helper method exists", file.exists());
}
+
+ @Test
+ public void testFilenameWhitelistFilter() {
+ final String[] expectedToAccept = new String[] { "one", "two", "three" };
+ final Set<String> whitelist = new HashSet<>(Arrays.asList(expectedToAccept));
+ final FilenameWhitelistFilter testFilter = new FilenameWhitelistFilter(whitelist);
+ for (final String str : expectedToAccept) {
+ assertTrue("Filename, " + str + ", in whitelist is accepted", testFilter.accept(testFile, str));
+ }
+
+ final String[] notExpectedToAccept = new String[] { "not-in-whitelist", "meh", "whatever" };
+ for (final String str : notExpectedToAccept) {
+ assertFalse("Filename, " + str + ", not in whitelist is not accepted", testFilter.accept(testFile, str));
+ }
+ }
+
+ @Test
+ public void testFilenameRegexFilter() {
+ final Pattern pattern = Pattern.compile("[a-z]{1,6}");
+ final FilenameRegexFilter testFilter = new FilenameRegexFilter(pattern);
+ final String[] expectedToAccept = new String[] { "duckie", "goes", "quack" };
+ for (final String str : expectedToAccept) {
+ assertTrue("Filename, " + str + ", matching regex expected to accept", testFilter.accept(testFile, str));
+ }
+
+ final String[] notExpectedToAccept = new String[] { "DUCKIE", "1337", "2fast" };
+ for (final String str : notExpectedToAccept) {
+ assertFalse("Filename, " + str + ", not matching regex not expected to accept", testFilter.accept(testFile, str));
+ }
+ }
}