Bug 1270213 - Move generic file filters to FileUtil. r=sebastian draft
authorMichael Comella <michael.l.comella@gmail.com>
Thu, 05 May 2016 17:10:57 -0700
changeset 364559 9d8a20548b82126d2dd9ff11744146dfa441b2f6
parent 363850 0e4859aa979d693ace332a960d929fa863951ce3
child 364560 477739d5bdb18dc311b59c8b09aa22e91ee4f272
push id17492
push usermichael.l.comella@gmail.com
push dateFri, 06 May 2016 21:43:40 +0000
reviewerssebastian
bugs1270213
milestone49.0a1
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
mobile/android/base/java/org/mozilla/gecko/util/FileUtils.java
mobile/android/tests/background/junit4/src/org/mozilla/gecko/util/TestFileUtils.java
--- 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));
+        }
+    }
 }