Use Files.isSameFile to check Resource equality (#6093)
Use Files.isSameFile to check Resource equality Avoid using canonical and instead use Files.isSameFile Signed-off-by: Greg Wilkins <gregw@webtide.com>
This commit is contained in:
parent
63810134c7
commit
ebe8311333
|
@ -20,7 +20,6 @@ package org.eclipse.jetty.deploy.providers;
|
|||
|
||||
import java.io.File;
|
||||
import java.io.FilenameFilter;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
@ -50,12 +49,11 @@ public abstract class ScanningAppProvider extends AbstractLifeCycle implements A
|
|||
{
|
||||
private static final Logger LOG = Log.getLogger(ScanningAppProvider.class);
|
||||
|
||||
private Map<String, App> _appMap = new HashMap<String, App>();
|
||||
private final Map<String, App> _appMap = new HashMap<>();
|
||||
|
||||
private DeploymentManager _deploymentManager;
|
||||
protected FilenameFilter _filenameFilter;
|
||||
private final List<Resource> _monitored = new CopyOnWriteArrayList<>();
|
||||
private final List<Resource> _canonicalMonitored = new CopyOnWriteArrayList<>();
|
||||
private boolean _recursive = false;
|
||||
private int _scanInterval = 10;
|
||||
private Scanner _scanner;
|
||||
|
@ -249,34 +247,12 @@ public abstract class ScanningAppProvider extends AbstractLifeCycle implements A
|
|||
{
|
||||
_monitored.clear();
|
||||
_monitored.addAll(resources);
|
||||
_canonicalMonitored.clear();
|
||||
for (Resource r : resources)
|
||||
{
|
||||
Resource canonical = r; //assume original is canonical
|
||||
try
|
||||
{
|
||||
File f = r.getFile(); //if it has a file, ensure it is canonical
|
||||
if (f != null)
|
||||
canonical = Resource.newResource(f.getCanonicalFile());
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
//use the original resource
|
||||
LOG.ignore(e);
|
||||
}
|
||||
_canonicalMonitored.add(canonical);
|
||||
}
|
||||
}
|
||||
|
||||
public List<Resource> getMonitoredResources()
|
||||
{
|
||||
return Collections.unmodifiableList(_monitored);
|
||||
}
|
||||
|
||||
List<Resource> getCanonicalMonitoredResources()
|
||||
{
|
||||
return Collections.unmodifiableList(_canonicalMonitored);
|
||||
}
|
||||
|
||||
public void setMonitoredDirResource(Resource resource)
|
||||
{
|
||||
|
|
|
@ -20,7 +20,6 @@ package org.eclipse.jetty.deploy.providers;
|
|||
|
||||
import java.io.File;
|
||||
import java.io.FilenameFilter;
|
||||
import java.io.IOException;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.eclipse.jetty.deploy.App;
|
||||
|
@ -79,62 +78,48 @@ public class WebAppProvider extends ScanningAppProvider
|
|||
@Override
|
||||
public boolean accept(File dir, String name)
|
||||
{
|
||||
if (dir == null)
|
||||
if (dir == null || !dir.exists())
|
||||
return false;
|
||||
|
||||
try
|
||||
{
|
||||
//Always work on canonical files because we need to
|
||||
//check if the file passed in is one of the
|
||||
//monitored resources
|
||||
if (!dir.getCanonicalFile().exists())
|
||||
return false;
|
||||
|
||||
String lowerName = name.toLowerCase(Locale.ENGLISH);
|
||||
String lowerName = name.toLowerCase(Locale.ENGLISH);
|
||||
|
||||
File canonical = new File(dir, name).getCanonicalFile();
|
||||
Resource r = Resource.newResource(canonical);
|
||||
if (getCanonicalMonitoredResources().contains(r) && r.isDirectory())
|
||||
Resource resource = Resource.newResource(new File(dir, name));
|
||||
for (Resource m : getMonitoredResources())
|
||||
if (resource.isSame(m))
|
||||
return false;
|
||||
|
||||
// ignore hidden files
|
||||
if (lowerName.startsWith("."))
|
||||
return false;
|
||||
|
||||
// Ignore some directories
|
||||
if (canonical.isDirectory())
|
||||
{
|
||||
// is it a nominated config directory
|
||||
if (lowerName.endsWith(".d"))
|
||||
return false;
|
||||
|
||||
// is it an unpacked directory for an existing war file?
|
||||
if (exists(name + ".war") || exists(name + ".WAR"))
|
||||
return false;
|
||||
|
||||
// is it a directory for an existing xml file?
|
||||
if (exists(name + ".xml") || exists(name + ".XML"))
|
||||
return false;
|
||||
|
||||
//is it a sccs dir?
|
||||
return !"cvs".equals(lowerName) && !"cvsroot".equals(lowerName); // OK to deploy it then
|
||||
}
|
||||
|
||||
// else is it a war file
|
||||
if (lowerName.endsWith(".war"))
|
||||
{
|
||||
//defer deployment decision to fileChanged()
|
||||
return true;
|
||||
}
|
||||
|
||||
// else is it a context XML file
|
||||
return lowerName.endsWith(".xml");
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
LOG.warn(e);
|
||||
// ignore hidden files
|
||||
if (lowerName.startsWith("."))
|
||||
return false;
|
||||
|
||||
// Ignore some directories
|
||||
if (resource.isDirectory())
|
||||
{
|
||||
// is it a nominated config directory
|
||||
if (lowerName.endsWith(".d"))
|
||||
return false;
|
||||
|
||||
// is it an unpacked directory for an existing war file?
|
||||
if (exists(name + ".war") || exists(name + ".WAR"))
|
||||
return false;
|
||||
|
||||
// is it a directory for an existing xml file?
|
||||
if (exists(name + ".xml") || exists(name + ".XML"))
|
||||
return false;
|
||||
|
||||
//is it a sccs dir?
|
||||
return !"cvs".equals(lowerName) && !"cvsroot".equals(lowerName); // OK to deploy it then
|
||||
}
|
||||
|
||||
// else is it a war file
|
||||
if (lowerName.endsWith(".war"))
|
||||
{
|
||||
//defer deployment decision to fileChanged()
|
||||
return true;
|
||||
}
|
||||
|
||||
// else is it a context XML file
|
||||
return lowerName.endsWith(".xml");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,9 @@ import java.net.URL;
|
|||
import java.net.URLConnection;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.InvalidPathException;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.security.Permission;
|
||||
|
||||
|
@ -184,6 +186,30 @@ public class FileResource extends Resource
|
|||
_alias = checkFileAlias(_uri, _file);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSame(Resource resource)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (resource instanceof PathResource)
|
||||
{
|
||||
Path path = ((PathResource)resource).getPath();
|
||||
return Files.isSameFile(getFile().toPath(), path);
|
||||
}
|
||||
if (resource instanceof FileResource)
|
||||
{
|
||||
Path path = ((FileResource)resource).getFile().toPath();
|
||||
return Files.isSameFile(getFile().toPath(), path);
|
||||
}
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("ignored", e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static URI normalizeURI(File file, URI uri) throws URISyntaxException
|
||||
{
|
||||
String u = uri.toASCIIString();
|
||||
|
|
|
@ -336,6 +336,30 @@ public class PathResource extends Resource
|
|||
this(url.toURI());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSame(Resource resource)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (resource instanceof PathResource)
|
||||
{
|
||||
Path path = ((PathResource)resource).getPath();
|
||||
return Files.isSameFile(getPath(), path);
|
||||
}
|
||||
if (resource instanceof FileResource)
|
||||
{
|
||||
Path path = ((FileResource)resource).getFile().toPath();
|
||||
return Files.isSameFile(getPath(), path);
|
||||
}
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("ignored", e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Resource addPath(final String subpath) throws IOException
|
||||
{
|
||||
|
|
|
@ -311,6 +311,18 @@ public abstract class Resource implements ResourceFactory, Closeable
|
|||
|
||||
public abstract boolean isContainedIn(Resource r) throws MalformedURLException;
|
||||
|
||||
/**
|
||||
* Return true if the passed Resource represents the same resource as the Resource.
|
||||
* For many resource types, this is equivalent to {@link #equals(Object)}, however
|
||||
* for resources types that support aliasing, this maybe some other check (e.g. {@link java.nio.file.Files#isSameFile(Path, Path)}).
|
||||
* @param resource The resource to check
|
||||
* @return true if the passed resource represents the same resource.
|
||||
*/
|
||||
public boolean isSame(Resource resource)
|
||||
{
|
||||
return equals(resource);
|
||||
}
|
||||
|
||||
/**
|
||||
* Release any temporary resources held by the resource.
|
||||
*
|
||||
|
|
|
@ -32,6 +32,7 @@ import java.util.HashMap;
|
|||
import java.util.Map;
|
||||
|
||||
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
@ -146,4 +147,20 @@ public class PathResourceTest
|
|||
File file = resource.getFile();
|
||||
assertThat("File for default FileSystem", file, is(exampleJar.toFile()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSame() throws Exception
|
||||
{
|
||||
Path rpath = MavenTestingUtils.getTestResourcePathFile("resource.txt");
|
||||
Path epath = MavenTestingUtils.getTestResourcePathFile("example.jar");
|
||||
PathResource rPathResource = new PathResource(rpath);
|
||||
FileResource rFileResource = new FileResource(rpath.toFile());
|
||||
PathResource ePathResource = new PathResource(epath);
|
||||
FileResource eFileResource = new FileResource(epath.toFile());
|
||||
|
||||
assertThat(rPathResource.isSame(rPathResource), Matchers.is(true));
|
||||
assertThat(rPathResource.isSame(rFileResource), Matchers.is(true));
|
||||
assertThat(rPathResource.isSame(ePathResource), Matchers.is(false));
|
||||
assertThat(rPathResource.isSame(eFileResource), Matchers.is(false));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue