* Fix #6114 Deploy symlink webapps Use Path.toRealPath rather than getCanonicalPath in the Scanner Make following symlinks configurable Signed-off-by: Greg Wilkins <gregw@webtide.com>
This commit is contained in:
parent
de37267ae5
commit
e3faf81860
|
@ -48,6 +48,7 @@ public abstract class ScanningAppProvider extends ContainerLifeCycle implements
|
|||
private final List<Resource> _monitored = new CopyOnWriteArrayList<>();
|
||||
private int _scanInterval = 10;
|
||||
private Scanner _scanner;
|
||||
private boolean _useRealPaths;
|
||||
|
||||
private final Scanner.DiscreteListener _scannerListener = new Scanner.DiscreteListener()
|
||||
{
|
||||
|
@ -81,6 +82,22 @@ public abstract class ScanningAppProvider extends ContainerLifeCycle implements
|
|||
addBean(_appMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return True if the real path of the scanned files should be used for deployment.
|
||||
*/
|
||||
public boolean isUseRealPaths()
|
||||
{
|
||||
return _useRealPaths;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param useRealPaths True if the real path of the scanned files should be used for deployment.
|
||||
*/
|
||||
public void setUseRealPaths(boolean useRealPaths)
|
||||
{
|
||||
_useRealPaths = useRealPaths;
|
||||
}
|
||||
|
||||
protected void setFilenameFilter(FilenameFilter filter)
|
||||
{
|
||||
if (isRunning())
|
||||
|
@ -128,7 +145,7 @@ public abstract class ScanningAppProvider extends ContainerLifeCycle implements
|
|||
LOG.warn("Does not exist: {}", resource);
|
||||
}
|
||||
|
||||
_scanner = new Scanner();
|
||||
_scanner = new Scanner(null, _useRealPaths);
|
||||
_scanner.setScanDirs(files);
|
||||
_scanner.setScanInterval(_scanInterval);
|
||||
_scanner.setFilenameFilter(_filenameFilter);
|
||||
|
|
|
@ -375,7 +375,7 @@ public class WebAppProvider extends ScanningAppProvider
|
|||
{
|
||||
//if a .xml file exists for it, then redeploy that instead
|
||||
File xml = new File(parent, xmlname);
|
||||
super.fileChanged(xml.getCanonicalPath());
|
||||
super.fileChanged(xml.getPath());
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -384,7 +384,7 @@ public class WebAppProvider extends ScanningAppProvider
|
|||
{
|
||||
//if a .XML file exists for it, then redeploy that instead
|
||||
File xml = new File(parent, xmlname);
|
||||
super.fileChanged(xml.getCanonicalPath());
|
||||
super.fileChanged(xml.getPath());
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
package org.eclipse.jetty.deploy.providers;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URL;
|
||||
import java.nio.file.FileSystemException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
@ -35,7 +34,6 @@ import org.eclipse.jetty.util.resource.Resource;
|
|||
import org.eclipse.jetty.webapp.WebAppContext;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.condition.EnabledOnOs;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
|
@ -45,7 +43,6 @@ import static org.junit.jupiter.api.Assertions.assertFalse;
|
|||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.junit.jupiter.api.Assumptions.assumeTrue;
|
||||
import static org.junit.jupiter.api.condition.OS.LINUX;
|
||||
import static org.junit.jupiter.api.condition.OS.MAC;
|
||||
|
||||
@ExtendWith(WorkDirExtension.class)
|
||||
public class WebAppProviderTest
|
||||
|
@ -68,10 +65,13 @@ public class WebAppProviderTest
|
|||
|
||||
// Make symlink
|
||||
Path pathWar3 = MavenTestingUtils.getTestResourcePathFile("webapps/foo-webapp-3.war");
|
||||
Path pathFoo = jetty.getJettyDir("webapps/foo.war").toPath();
|
||||
Path pathBar = jetty.getJettyDir("webapps/bar.war").toPath();
|
||||
Path pathBob = jetty.getJettyDir("webapps/bob.war").toPath();
|
||||
try
|
||||
{
|
||||
Files.createSymbolicLink(pathBar, pathWar3);
|
||||
Files.createSymbolicLink(pathBob, pathFoo);
|
||||
symlinkSupported = true;
|
||||
}
|
||||
catch (UnsupportedOperationException | FileSystemException e)
|
||||
|
@ -95,12 +95,11 @@ public class WebAppProviderTest
|
|||
jetty.stop();
|
||||
}
|
||||
|
||||
@Disabled("See issue #1200")
|
||||
@Test
|
||||
public void testStartupContext()
|
||||
{
|
||||
// Check Server for Handlers
|
||||
jetty.assertWebAppContextsExists("/bar", "/foo");
|
||||
jetty.assertWebAppContextsExists("/bar", "/foo", "/bob");
|
||||
|
||||
File workDir = jetty.getJettyDir("workish");
|
||||
|
||||
|
@ -109,10 +108,9 @@ public class WebAppProviderTest
|
|||
assertDirNotExists("root of work directory", workDir, "jsp");
|
||||
|
||||
// Test for correct behaviour
|
||||
assertTrue(hasJettyGeneratedPath(workDir, "foo.war"), "Should have generated directory in work directory: " + workDir);
|
||||
assertTrue(hasJettyGeneratedPath(workDir, "foo_war"), "Should have generated directory in work directory: " + workDir);
|
||||
}
|
||||
|
||||
@Disabled("See issue #1200")
|
||||
@Test
|
||||
public void testStartupSymlinkContext()
|
||||
{
|
||||
|
@ -124,11 +122,11 @@ public class WebAppProviderTest
|
|||
assertTrue(barLink.isFile(), "bar.war link isFile: " + barLink.toString());
|
||||
|
||||
// Check Server for expected Handlers
|
||||
jetty.assertWebAppContextsExists("/bar", "/foo");
|
||||
jetty.assertWebAppContextsExists("/bar", "/foo", "/bob");
|
||||
|
||||
// Test for expected work/temp directory behaviour
|
||||
File workDir = jetty.getJettyDir("workish");
|
||||
assertTrue(hasJettyGeneratedPath(workDir, "bar.war"), "Should have generated directory in work directory: " + workDir);
|
||||
assertTrue(hasJettyGeneratedPath(workDir, "bar_war"), "Should have generated directory in work directory: " + workDir);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
<Set name="monitoredDirName"><SystemProperty name="jetty.home" />/webapps</Set>
|
||||
<Set name="scanInterval">1</Set>
|
||||
<Set name="tempDir"><Property name="jetty.home" default="target" />/workish</Set>
|
||||
<Set name="useRealPaths">false</Set>
|
||||
</New>
|
||||
</Item>
|
||||
</Array>
|
||||
|
|
|
@ -20,6 +20,7 @@ import java.nio.file.FileVisitOption;
|
|||
import java.nio.file.FileVisitResult;
|
||||
import java.nio.file.FileVisitor;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.LinkOption;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.PathMatcher;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
|
@ -35,6 +36,7 @@ import java.util.concurrent.CopyOnWriteArrayList;
|
|||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.eclipse.jetty.util.component.ContainerLifeCycle;
|
||||
import org.eclipse.jetty.util.thread.ScheduledExecutorScheduler;
|
||||
|
@ -47,6 +49,8 @@ import org.slf4j.LoggerFactory;
|
|||
*
|
||||
* Utility for scanning a directory for added, removed and changed
|
||||
* files and reporting these events via registered Listeners.
|
||||
* The scanner operates on the {@link Path#toRealPath(LinkOption...)} of the files scanned and
|
||||
* can be configured to follow symlinks.
|
||||
*/
|
||||
public class Scanner extends ContainerLifeCycle
|
||||
{
|
||||
|
@ -63,7 +67,7 @@ public class Scanner extends ContainerLifeCycle
|
|||
private int _scanInterval;
|
||||
private final AtomicInteger _scanCount = new AtomicInteger(0);
|
||||
private final List<Listener> _listeners = new CopyOnWriteArrayList<>();
|
||||
private Map<String, MetaData> _prevScan;
|
||||
private Map<Path, MetaData> _prevScan;
|
||||
private FilenameFilter _filter;
|
||||
private final Map<Path, IncludeExcludeSet<PathMatcher, Path>> _scannables = new ConcurrentHashMap<>();
|
||||
private boolean _reportExisting = true;
|
||||
|
@ -71,6 +75,7 @@ public class Scanner extends ContainerLifeCycle
|
|||
private Scheduler.Task _task;
|
||||
private final Scheduler _scheduler;
|
||||
private int _scanDepth = DEFAULT_SCAN_DEPTH;
|
||||
private final LinkOption[] _linkOptions;
|
||||
|
||||
private enum Status
|
||||
{
|
||||
|
@ -150,11 +155,11 @@ public class Scanner extends ContainerLifeCycle
|
|||
*/
|
||||
private class Visitor implements FileVisitor<Path>
|
||||
{
|
||||
Map<String, MetaData> scanInfoMap;
|
||||
Map<Path, MetaData> scanInfoMap;
|
||||
IncludeExcludeSet<PathMatcher, Path> rootIncludesExcludes;
|
||||
Path root;
|
||||
|
||||
public Visitor(Path root, IncludeExcludeSet<PathMatcher, Path> rootIncludesExcludes, Map<String, MetaData> scanInfoMap)
|
||||
private Visitor(Path root, IncludeExcludeSet<PathMatcher, Path> rootIncludesExcludes, Map<Path, MetaData> scanInfoMap)
|
||||
{
|
||||
this.root = root;
|
||||
this.rootIncludesExcludes = rootIncludesExcludes;
|
||||
|
@ -167,10 +172,11 @@ public class Scanner extends ContainerLifeCycle
|
|||
if (!Files.exists(dir))
|
||||
return FileVisitResult.SKIP_SUBTREE;
|
||||
|
||||
dir = dir.toRealPath(_linkOptions);
|
||||
File f = dir.toFile();
|
||||
|
||||
//if we want to report directories and we haven't already seen it
|
||||
if (_reportDirs && !scanInfoMap.containsKey(f.getCanonicalPath()))
|
||||
if (_reportDirs && !scanInfoMap.containsKey(dir))
|
||||
{
|
||||
boolean accepted = false;
|
||||
if (rootIncludesExcludes != null && !rootIncludesExcludes.isEmpty())
|
||||
|
@ -186,7 +192,7 @@ public class Scanner extends ContainerLifeCycle
|
|||
|
||||
if (accepted)
|
||||
{
|
||||
scanInfoMap.put(f.getCanonicalPath(), new MetaData(f.lastModified(), f.isDirectory() ? 0 : f.length()));
|
||||
scanInfoMap.put(dir, new MetaData(f.lastModified(), f.isDirectory() ? 0 : f.length()));
|
||||
if (LOG.isDebugEnabled()) LOG.debug("scan accepted dir {} mod={}", f, f.lastModified());
|
||||
}
|
||||
}
|
||||
|
@ -195,20 +201,22 @@ public class Scanner extends ContainerLifeCycle
|
|||
}
|
||||
|
||||
@Override
|
||||
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException
|
||||
public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) throws IOException
|
||||
{
|
||||
if (!Files.exists(file))
|
||||
path = path.toRealPath(_linkOptions);
|
||||
|
||||
if (!Files.exists(path))
|
||||
return FileVisitResult.CONTINUE;
|
||||
|
||||
File f = file.toFile();
|
||||
File f = path.toFile();
|
||||
boolean accepted = false;
|
||||
|
||||
if (f.isFile() || (f.isDirectory() && _reportDirs && !scanInfoMap.containsKey(f.getCanonicalPath())))
|
||||
if (f.isFile() || (f.isDirectory() && _reportDirs && !scanInfoMap.containsKey(path)))
|
||||
{
|
||||
if (rootIncludesExcludes != null && !rootIncludesExcludes.isEmpty())
|
||||
{
|
||||
//accepted if not explicitly excluded and either is explicitly included or there are no explicit inclusions
|
||||
accepted = rootIncludesExcludes.test(file);
|
||||
accepted = rootIncludesExcludes.test(path);
|
||||
}
|
||||
else if (_filter == null || _filter.accept(f.getParentFile(), f.getName()))
|
||||
accepted = true;
|
||||
|
@ -216,7 +224,7 @@ public class Scanner extends ContainerLifeCycle
|
|||
|
||||
if (accepted)
|
||||
{
|
||||
scanInfoMap.put(f.getCanonicalPath(), new MetaData(f.lastModified(), f.isDirectory() ? 0 : f.length()));
|
||||
scanInfoMap.put(path, new MetaData(f.lastModified(), f.isDirectory() ? 0 : f.length()));
|
||||
if (LOG.isDebugEnabled()) LOG.debug("scan accepted {} mod={}", f, f.lastModified());
|
||||
}
|
||||
|
||||
|
@ -251,10 +259,62 @@ public class Scanner extends ContainerLifeCycle
|
|||
*/
|
||||
public interface DiscreteListener extends Listener
|
||||
{
|
||||
/**
|
||||
* Called when a file is changed.
|
||||
* Default implementation calls {@link #fileChanged(String)}.
|
||||
* @param path the {@link Path#toRealPath(LinkOption...)} of the changed file
|
||||
* @throws Exception May be thrown for handling errors
|
||||
*/
|
||||
default void pathChanged(Path path) throws Exception
|
||||
{
|
||||
path.toString();
|
||||
fileChanged(path.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a file is added.
|
||||
* Default implementation calls {@link #fileAdded(String)}.
|
||||
* @param path the {@link Path#toRealPath(LinkOption...)} of the added file
|
||||
* @throws Exception May be thrown for handling errors
|
||||
*/
|
||||
default void pathAdded(Path path) throws Exception
|
||||
{
|
||||
fileAdded(path.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a file is removed.
|
||||
* Default implementation calls {@link #fileRemoved(String)}.
|
||||
* @param path the {@link Path#toRealPath(LinkOption...)} of the removed file
|
||||
* @throws Exception May be thrown for handling errors
|
||||
*/
|
||||
default void pathRemoved(Path path) throws Exception
|
||||
{
|
||||
fileRemoved(path.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a file is changed.
|
||||
* May not be called if {@link #pathChanged(Path)} is overridden.
|
||||
* @param filename the {@link Path#toRealPath(LinkOption...)} as a string of the changed file
|
||||
* @throws Exception May be thrown for handling errors
|
||||
*/
|
||||
void fileChanged(String filename) throws Exception;
|
||||
|
||||
/**
|
||||
* Called when a file is added.
|
||||
* May not be called if {@link #pathAdded(Path)} is overridden.
|
||||
* @param filename the {@link Path#toRealPath(LinkOption...)} as a string of the added file
|
||||
* @throws Exception May be thrown for handling errors
|
||||
*/
|
||||
void fileAdded(String filename) throws Exception;
|
||||
|
||||
/**
|
||||
* Called when a file is removed.
|
||||
* May not be called if {@link #pathRemoved(Path)} is overridden.
|
||||
* @param filename the {@link Path#toRealPath(LinkOption...)} as a string of the removed file
|
||||
* @throws Exception May be thrown for handling errors
|
||||
*/
|
||||
void fileRemoved(String filename) throws Exception;
|
||||
}
|
||||
|
||||
|
@ -263,7 +323,12 @@ public class Scanner extends ContainerLifeCycle
|
|||
*/
|
||||
public interface BulkListener extends Listener
|
||||
{
|
||||
public void filesChanged(Set<String> filenames) throws Exception;
|
||||
default void pathsChanged(Set<Path> paths) throws Exception
|
||||
{
|
||||
filesChanged(paths.stream().map(Path::toString).collect(Collectors.toSet()));
|
||||
}
|
||||
|
||||
void filesChanged(Set<String> filenames) throws Exception;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -282,14 +347,24 @@ public class Scanner extends ContainerLifeCycle
|
|||
|
||||
public Scanner()
|
||||
{
|
||||
this(new ScheduledExecutorScheduler("Scanner-" + SCANNER_IDS.getAndIncrement(), true, 1));
|
||||
this(null);
|
||||
}
|
||||
|
||||
public Scanner(Scheduler scheduler)
|
||||
{
|
||||
this(scheduler, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param scheduler The scheduler to use for scanning.
|
||||
* @param reportRealPaths If true, the {@link Listener}s are called with the real path of scanned files.
|
||||
*/
|
||||
public Scanner(Scheduler scheduler, boolean reportRealPaths)
|
||||
{
|
||||
//Create the scheduler and start it
|
||||
_scheduler = scheduler;
|
||||
_scheduler = scheduler == null ? new ScheduledExecutorScheduler("Scanner-" + SCANNER_IDS.getAndIncrement(), true, 1) : scheduler;
|
||||
addBean(_scheduler);
|
||||
_linkOptions = reportRealPaths ? new LinkOption[0] : new LinkOption[] {LinkOption.NOFOLLOW_LINKS};
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -335,21 +410,24 @@ public class Scanner extends ContainerLifeCycle
|
|||
/**
|
||||
* Add a file to be scanned. The file must not be null, and must exist.
|
||||
*
|
||||
* @param p the Path of the file to scan.
|
||||
* @param path the Path of the file to scan.
|
||||
*/
|
||||
public void addFile(Path p)
|
||||
public void addFile(Path path)
|
||||
{
|
||||
if (isRunning())
|
||||
throw new IllegalStateException("Scanner started");
|
||||
|
||||
if (p == null)
|
||||
if (path == null)
|
||||
throw new IllegalStateException("Null path");
|
||||
|
||||
if (!Files.exists(p) || Files.isDirectory(p))
|
||||
throw new IllegalStateException("Not file or doesn't exist: " + p);
|
||||
try
|
||||
{
|
||||
_scannables.putIfAbsent(p.toRealPath(), new IncludeExcludeSet<>(PathMatcherSet.class));
|
||||
// Always follow links when check ultimate type of the path
|
||||
Path real = path.toRealPath();
|
||||
if (!Files.exists(real) || Files.isDirectory(real))
|
||||
throw new IllegalStateException("Not file or doesn't exist: " + path);
|
||||
|
||||
_scannables.putIfAbsent(real, new IncludeExcludeSet<>(PathMatcherSet.class));
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
|
@ -371,13 +449,15 @@ public class Scanner extends ContainerLifeCycle
|
|||
if (p == null)
|
||||
throw new IllegalStateException("Null path");
|
||||
|
||||
if (!Files.exists(p) || !Files.isDirectory(p))
|
||||
throw new IllegalStateException("Not directory or doesn't exist: " + p);
|
||||
|
||||
try
|
||||
{
|
||||
// Check status of the real path
|
||||
Path real = p.toRealPath();
|
||||
if (!Files.exists(real) || !Files.isDirectory(real))
|
||||
throw new IllegalStateException("Not directory or doesn't exist: " + p);
|
||||
|
||||
IncludeExcludeSet<PathMatcher, Path> includesExcludes = new IncludeExcludeSet<>(PathMatcherSet.class);
|
||||
IncludeExcludeSet<PathMatcher, Path> prev = _scannables.putIfAbsent(p.toRealPath(), includesExcludes);
|
||||
IncludeExcludeSet<PathMatcher, Path> prev = _scannables.putIfAbsent(real, includesExcludes);
|
||||
if (prev != null)
|
||||
includesExcludes = prev;
|
||||
return includesExcludes;
|
||||
|
@ -625,7 +705,7 @@ public class Scanner extends ContainerLifeCycle
|
|||
{
|
||||
int cycle = _scanCount.incrementAndGet();
|
||||
reportScanStart(cycle);
|
||||
Map<String, MetaData> currentScan = scanFiles();
|
||||
Map<Path, MetaData> currentScan = scanFiles();
|
||||
reportDifferences(currentScan, _prevScan == null ? Collections.emptyMap() : Collections.unmodifiableMap(_prevScan));
|
||||
_prevScan = currentScan;
|
||||
reportScanEnd(cycle);
|
||||
|
@ -634,9 +714,9 @@ public class Scanner extends ContainerLifeCycle
|
|||
/**
|
||||
* Scan all of the given paths.
|
||||
*/
|
||||
private Map<String, MetaData> scanFiles()
|
||||
private Map<Path, MetaData> scanFiles()
|
||||
{
|
||||
Map<String, MetaData> currentScan = new HashMap<>();
|
||||
Map<Path, MetaData> currentScan = new HashMap<>();
|
||||
for (Map.Entry<Path, IncludeExcludeSet<PathMatcher, Path>> entry : _scannables.entrySet())
|
||||
{
|
||||
try
|
||||
|
@ -660,20 +740,20 @@ public class Scanner extends ContainerLifeCycle
|
|||
* @param currentScan the info from the most recent pass
|
||||
* @param oldScan info from the previous pass
|
||||
*/
|
||||
private void reportDifferences(Map<String, MetaData> currentScan, Map<String, MetaData> oldScan)
|
||||
private void reportDifferences(Map<Path, MetaData> currentScan, Map<Path, MetaData> oldScan)
|
||||
{
|
||||
Map<String, Notification> changes = new HashMap<>();
|
||||
Map<Path, Notification> changes = new HashMap<>();
|
||||
|
||||
//Handle deleted files
|
||||
Set<String> oldScanKeys = new HashSet<>(oldScan.keySet());
|
||||
Set<Path> oldScanKeys = new HashSet<>(oldScan.keySet());
|
||||
oldScanKeys.removeAll(currentScan.keySet());
|
||||
for (String file : oldScanKeys)
|
||||
for (Path path : oldScanKeys)
|
||||
{
|
||||
changes.put(file, Notification.REMOVED);
|
||||
changes.put(path, Notification.REMOVED);
|
||||
}
|
||||
|
||||
// Handle new and changed files
|
||||
for (Map.Entry<String, MetaData> entry : currentScan.entrySet())
|
||||
for (Map.Entry<Path, MetaData> entry : currentScan.entrySet())
|
||||
{
|
||||
MetaData current = entry.getValue();
|
||||
MetaData previous = oldScan.get(entry.getKey());
|
||||
|
@ -714,7 +794,7 @@ public class Scanner extends ContainerLifeCycle
|
|||
LOG.debug("scanned {}", _scannables.keySet());
|
||||
|
||||
//Call the DiscreteListeners
|
||||
for (Map.Entry<String, Notification> entry : changes.entrySet())
|
||||
for (Map.Entry<Path, Notification> entry : changes.entrySet())
|
||||
{
|
||||
switch (entry.getValue())
|
||||
{
|
||||
|
@ -736,28 +816,28 @@ public class Scanner extends ContainerLifeCycle
|
|||
reportBulkChanges(changes.keySet());
|
||||
}
|
||||
|
||||
private void warn(Object listener, String filename, Throwable th)
|
||||
private void warn(Object listener, Path path, Throwable th)
|
||||
{
|
||||
LOG.warn("{} failed on '{}'", listener, filename, th);
|
||||
LOG.warn("{} failed on '{}'", listener, path, th);
|
||||
}
|
||||
|
||||
/**
|
||||
* Report a file addition to the registered FileAddedListeners
|
||||
*
|
||||
* @param filename the filename
|
||||
* @param path the path
|
||||
*/
|
||||
private void reportAddition(String filename)
|
||||
private void reportAddition(Path path)
|
||||
{
|
||||
for (Listener l : _listeners)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (l instanceof DiscreteListener)
|
||||
((DiscreteListener)l).fileAdded(filename);
|
||||
((DiscreteListener)l).pathAdded(path);
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
warn(l, filename, e);
|
||||
warn(l, path, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -765,20 +845,20 @@ public class Scanner extends ContainerLifeCycle
|
|||
/**
|
||||
* Report a file removal to the FileRemovedListeners
|
||||
*
|
||||
* @param filename the filename
|
||||
* @param path the path of the removed filename
|
||||
*/
|
||||
private void reportRemoval(String filename)
|
||||
private void reportRemoval(Path path)
|
||||
{
|
||||
for (Object l : _listeners)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (l instanceof DiscreteListener)
|
||||
((DiscreteListener)l).fileRemoved(filename);
|
||||
((DiscreteListener)l).pathRemoved(path);
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
warn(l, filename, e);
|
||||
warn(l, path, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -786,11 +866,11 @@ public class Scanner extends ContainerLifeCycle
|
|||
/**
|
||||
* Report a file change to the FileChangedListeners
|
||||
*
|
||||
* @param filename the filename
|
||||
* @param path the path of the changed file
|
||||
*/
|
||||
private void reportChange(String filename)
|
||||
private void reportChange(Path path)
|
||||
{
|
||||
if (filename == null)
|
||||
if (path == null)
|
||||
return;
|
||||
|
||||
for (Listener l : _listeners)
|
||||
|
@ -798,11 +878,11 @@ public class Scanner extends ContainerLifeCycle
|
|||
try
|
||||
{
|
||||
if (l instanceof DiscreteListener)
|
||||
((DiscreteListener)l).fileChanged(filename);
|
||||
((DiscreteListener)l).pathChanged(path);
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
warn(l, filename, e);
|
||||
warn(l, path, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -810,11 +890,11 @@ public class Scanner extends ContainerLifeCycle
|
|||
/**
|
||||
* Report the list of filenames for which changes were detected.
|
||||
*
|
||||
* @param filenames names of all files added/changed/removed
|
||||
* @param paths The paths of all files added/changed/removed
|
||||
*/
|
||||
private void reportBulkChanges(Set<String> filenames)
|
||||
private void reportBulkChanges(Set<Path> paths)
|
||||
{
|
||||
if (filenames == null || filenames.isEmpty())
|
||||
if (paths == null || paths.isEmpty())
|
||||
return;
|
||||
|
||||
for (Listener l : _listeners)
|
||||
|
@ -822,11 +902,11 @@ public class Scanner extends ContainerLifeCycle
|
|||
try
|
||||
{
|
||||
if (l instanceof BulkListener)
|
||||
((BulkListener)l).filesChanged(filenames);
|
||||
((BulkListener)l).pathsChanged(paths);
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
warn(l, filenames.toString(), e);
|
||||
LOG.warn("{} failed on '{}'", l, paths, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue