FELIX-5137 Added felix.fileinstall.subdir.mode = jar | skip | recurse
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1719952 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/DirectoryWatcher.java b/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/DirectoryWatcher.java
index 4013dc0..f73b3ea 100644
--- a/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/DirectoryWatcher.java
+++ b/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/DirectoryWatcher.java
@@ -106,6 +106,7 @@
public final static String OPTIONAL_SCOPE = "felix.fileinstall.optionalImportRefreshScope";
public final static String FRAGMENT_SCOPE = "felix.fileinstall.fragmentRefreshScope";
public final static String DISABLE_NIO2 = "felix.fileinstall.disableNio2";
+ public final static String SUBDIR_MODE = "felix.fileinstall.subdir.mode";
public final static String SCOPE_NONE = "none";
public final static String SCOPE_MANAGED = "managed";
@@ -185,12 +186,12 @@
this.context.addBundleListener(this);
if (disableNio2) {
- scanner = new Scanner(watchedDirectory, filter);
+ scanner = new Scanner(watchedDirectory, filter, properties.get(SUBDIR_MODE));
} else {
try {
- scanner = new WatcherScanner(context, watchedDirectory, filter);
+ scanner = new WatcherScanner(context, watchedDirectory, filter, properties.get(SUBDIR_MODE));
} catch (Throwable t) {
- scanner = new Scanner(watchedDirectory, filter);
+ scanner = new Scanner(watchedDirectory, filter, properties.get(SUBDIR_MODE));
}
}
}
diff --git a/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/FileInstall.java b/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/FileInstall.java
index c94bde2..bd29152 100644
--- a/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/FileInstall.java
+++ b/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/FileInstall.java
@@ -104,6 +104,7 @@
set(ht, DirectoryWatcher.NO_INITIAL_DELAY);
set(ht, DirectoryWatcher.START_LEVEL);
set(ht, DirectoryWatcher.OPTIONAL_SCOPE);
+ set(ht, DirectoryWatcher.SUBDIR_MODE);
// check if dir is an array of dirs
String dirs = ht.get(DirectoryWatcher.DIR);
diff --git a/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/Scanner.java b/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/Scanner.java
index 985c2ba..7fad43a 100644
--- a/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/Scanner.java
+++ b/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/Scanner.java
@@ -44,8 +44,15 @@
*/
public class Scanner implements Closeable {
+ public final static String SUBDIR_MODE_JAR = "jar";
+ public final static String SUBDIR_MODE_SKIP = "skip";
+ public final static String SUBDIR_MODE_RECURSE = "recurse";
+
final File directory;
final FilenameFilter filter;
+ final boolean jarSubdir;
+ final boolean skipSubdir;
+ final boolean recurseSubdir;
// Store checksums of files or directories
Map<File, Long> lastChecksums = new HashMap<File, Long>();
@@ -58,7 +65,7 @@
*/
public Scanner(File directory)
{
- this(directory, null);
+ this(directory, null, null);
}
/**
@@ -66,8 +73,9 @@
*
* @param directory the directory to scan
* @param filterString a filter for file names
+ * @param subdirMode to use when scanning
*/
- public Scanner(File directory, final String filterString)
+ public Scanner(File directory, final String filterString, String subdirMode)
{
this.directory = canon(directory);
if (filterString != null && filterString.length() > 0)
@@ -85,6 +93,9 @@
{
this.filter = null;
}
+ this.jarSubdir = subdirMode == null || SUBDIR_MODE_JAR.equals(subdirMode);
+ this.skipSubdir = SUBDIR_MODE_SKIP.equals(subdirMode);
+ this.recurseSubdir = SUBDIR_MODE_RECURSE.equals(subdirMode);
}
/**
@@ -117,25 +128,44 @@
{
return null;
}
+ return processFiles(reportImmediately, list);
+ }
+
+ private Set<File> processFiles(boolean reportImmediately, File[] list)
+ {
Set<File> files = new HashSet<File>();
Set<File> removed = new HashSet<File>(storedChecksums.keySet());
for (File file : list)
{
+ if (file.isDirectory())
+ {
+ if (skipSubdir)
+ {
+ continue;
+ }
+ else if (recurseSubdir)
+ {
+ files.addAll(processFiles(reportImmediately, file.listFiles(filter)));
+ continue;
+ }
+ }
long lastChecksum = lastChecksums.get(file) != null ? (Long) lastChecksums.get(file) : 0;
long storedChecksum = storedChecksums.get(file) != null ? (Long) storedChecksums.get(file) : 0;
long newChecksum = checksum(file);
lastChecksums.put(file, newChecksum);
- // Only handle file when it does not change anymore and it has changed since last reported
- if ((newChecksum == lastChecksum || reportImmediately) && newChecksum != storedChecksum) {
+ // Only handle file when it does not change anymore and it has changed
+ // since last reported
+ if ((newChecksum == lastChecksum || reportImmediately) && newChecksum != storedChecksum)
+ {
storedChecksums.put(file, newChecksum);
files.add(file);
}
removed.remove(file);
}
+ // Make sure we'll handle a file that has been deleted
+ files.addAll(removed);
for (File file : removed)
{
- // Make sure we'll handle a file that has been deleted
- files.addAll(removed);
// Remove no longer used checksums
lastChecksums.remove(file);
storedChecksums.remove(file);
diff --git a/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/WatcherScanner.java b/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/WatcherScanner.java
index 11f02ed..532356f 100644
--- a/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/WatcherScanner.java
+++ b/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/WatcherScanner.java
@@ -42,9 +42,10 @@
*
* @param directory the directory to scan
* @param filterString a filter for file names
+ * @param subdirMode to use when scanning
*/
- public WatcherScanner(BundleContext bundleContext, File directory, String filterString) throws IOException {
- super(directory, filterString);
+ public WatcherScanner(BundleContext bundleContext, File directory, String filterString, String subdirMode) throws IOException {
+ super(directory, filterString, subdirMode);
this.bundleContext = bundleContext;
if (filterString != null) {
this.fileMatcher = FileSystems.getDefault().getPathMatcher("regex:" + filterString);
@@ -115,11 +116,23 @@
@Override
protected void process(Path path) {
File file = path.toFile();
- while (!file.getParentFile().equals(directory)) {
- file = file.getParentFile();
- if (file == null) {
+ if (!file.getParentFile().equals(directory)) {
+ // File is in a sub directory.
+ if (skipSubdir) {
+ return;
+ }
+ if (jarSubdir) {
+ // Walk up until the first level sub-directory.
+ do {
+ file = file.getParentFile();
+ if (file == null) {
+ // The file was not actually inside the watched directory.
+ // Should not happen.
return;
- }
+ }
+ } while (!file.getParentFile().equals(directory));
+ }
+ // Otherwise we recurse by adding the file as-is.
}
synchronized (changed) {
changed.add(file);
@@ -128,16 +141,7 @@
@Override
protected void onRemove(Path path) {
- File file = path.toFile();
- while (!file.getParentFile().equals(directory)) {
- file = file.getParentFile();
- if (file == null) {
- return;
- }
- }
- synchronized (changed) {
- changed.add(file);
- }
+ process(path);
}
@Override