Replace "folder" with "directory"
Consistently use the term "directory" instead of "folder" Closes gh-21218
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,7 +19,7 @@ package org.springframework.boot.devtools.autoconfigure;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
import org.springframework.boot.devtools.classpath.ClassPathFolders;
|
||||
import org.springframework.boot.devtools.classpath.ClassPathDirectories;
|
||||
import org.springframework.boot.devtools.filewatch.ChangedFiles;
|
||||
import org.springframework.boot.devtools.filewatch.FileChangeListener;
|
||||
import org.springframework.boot.devtools.filewatch.FileSystemWatcher;
|
||||
@@ -44,7 +44,7 @@ class FileWatchingFailureHandler implements FailureHandler {
|
||||
public Outcome handle(Throwable failure) {
|
||||
CountDownLatch latch = new CountDownLatch(1);
|
||||
FileSystemWatcher watcher = this.fileSystemWatcherFactory.getFileSystemWatcher();
|
||||
watcher.addSourceFolders(new ClassPathFolders(Restarter.getInstance().getInitialUrls()));
|
||||
watcher.addSourceDirectories(new ClassPathDirectories(Restarter.getInstance().getInitialUrls()));
|
||||
watcher.addListener(new Listener(latch));
|
||||
watcher.start();
|
||||
try {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -148,7 +148,7 @@ public class LocalDevToolsAutoConfiguration {
|
||||
}
|
||||
List<File> additionalPaths = restartProperties.getAdditionalPaths();
|
||||
for (File path : additionalPaths) {
|
||||
watcher.addSourceFolder(path.getAbsoluteFile());
|
||||
watcher.addSourceDirectory(path.getAbsoluteFile());
|
||||
}
|
||||
return watcher;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -40,10 +40,10 @@ import org.springframework.boot.devtools.remote.server.HandlerMapper;
|
||||
import org.springframework.boot.devtools.remote.server.HttpHeaderAccessManager;
|
||||
import org.springframework.boot.devtools.remote.server.HttpStatusHandler;
|
||||
import org.springframework.boot.devtools.remote.server.UrlHandlerMapper;
|
||||
import org.springframework.boot.devtools.restart.server.DefaultSourceFolderUrlFilter;
|
||||
import org.springframework.boot.devtools.restart.server.DefaultSourceDirectoryUrlFilter;
|
||||
import org.springframework.boot.devtools.restart.server.HttpRestartServer;
|
||||
import org.springframework.boot.devtools.restart.server.HttpRestartServerHandler;
|
||||
import org.springframework.boot.devtools.restart.server.SourceFolderUrlFilter;
|
||||
import org.springframework.boot.devtools.restart.server.SourceDirectoryUrlFilter;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Conditional;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@@ -109,14 +109,14 @@ public class RemoteDevToolsAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
SourceFolderUrlFilter remoteRestartSourceFolderUrlFilter() {
|
||||
return new DefaultSourceFolderUrlFilter();
|
||||
SourceDirectoryUrlFilter remoteRestartSourceDirectoryUrlFilter() {
|
||||
return new DefaultSourceDirectoryUrlFilter();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
HttpRestartServer remoteRestartHttpRestartServer(SourceFolderUrlFilter sourceFolderUrlFilter) {
|
||||
return new HttpRestartServer(sourceFolderUrlFilter);
|
||||
HttpRestartServer remoteRestartHttpRestartServer(SourceDirectoryUrlFilter sourceDirectoryUrlFilter) {
|
||||
return new HttpRestartServer(sourceDirectoryUrlFilter);
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -30,18 +30,18 @@ import org.springframework.core.log.LogMessage;
|
||||
import org.springframework.util.ResourceUtils;
|
||||
|
||||
/**
|
||||
* Provides access to entries on the classpath that refer to folders.
|
||||
* Provides access to entries on the classpath that refer to directories.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @since 1.3.0
|
||||
* @since 2.3.0
|
||||
*/
|
||||
public class ClassPathFolders implements Iterable<File> {
|
||||
public class ClassPathDirectories implements Iterable<File> {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(ClassPathFolders.class);
|
||||
private static final Log logger = LogFactory.getLog(ClassPathDirectories.class);
|
||||
|
||||
private final List<File> folders = new ArrayList<>();
|
||||
private final List<File> directories = new ArrayList<>();
|
||||
|
||||
public ClassPathFolders(URL[] urls) {
|
||||
public ClassPathDirectories(URL[] urls) {
|
||||
if (urls != null) {
|
||||
addUrls(urls);
|
||||
}
|
||||
@@ -56,7 +56,7 @@ public class ClassPathFolders implements Iterable<File> {
|
||||
private void addUrl(URL url) {
|
||||
if (url.getProtocol().equals("file") && url.getPath().endsWith("/")) {
|
||||
try {
|
||||
this.folders.add(ResourceUtils.getFile(url));
|
||||
this.directories.add(ResourceUtils.getFile(url));
|
||||
}
|
||||
catch (Exception ex) {
|
||||
logger.warn(LogMessage.format("Unable to get classpath URL %s", url));
|
||||
@@ -67,7 +67,7 @@ public class ClassPathFolders implements Iterable<File> {
|
||||
|
||||
@Override
|
||||
public Iterator<File> iterator() {
|
||||
return Collections.unmodifiableList(this.folders).iterator();
|
||||
return Collections.unmodifiableList(this.directories).iterator();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -28,7 +28,7 @@ import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Encapsulates a {@link FileSystemWatcher} to watch the local classpath folders for
|
||||
* Encapsulates a {@link FileSystemWatcher} to watch the local classpath directories for
|
||||
* changes.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
@@ -58,7 +58,7 @@ public class ClassPathFileSystemWatcher implements InitializingBean, DisposableB
|
||||
Assert.notNull(urls, "Urls must not be null");
|
||||
this.fileSystemWatcher = fileSystemWatcherFactory.getFileSystemWatcher();
|
||||
this.restartStrategy = restartStrategy;
|
||||
this.fileSystemWatcher.addSourceFolders(new ClassPathFolders(urls));
|
||||
this.fileSystemWatcher.addSourceDirectories(new ClassPathDirectories(urls));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -40,7 +40,7 @@ import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* {@link EnvironmentPostProcessor} to add devtools properties from the user's home
|
||||
* folder.
|
||||
* directory.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @author Andy Wilkinson
|
||||
@@ -93,7 +93,7 @@ public class DevToolsHomePropertiesPostProcessor implements EnvironmentPostProce
|
||||
|
||||
private void addPropertySource(List<PropertySource<?>> propertySources, String fileName,
|
||||
Function<File, String> propertySourceNamer) {
|
||||
File home = getHomeFolder();
|
||||
File home = getHomeDirectory();
|
||||
File file = (home != null) ? new File(home, fileName) : null;
|
||||
FileSystemResource resource = (file != null) ? new FileSystemResource(file) : null;
|
||||
if (resource != null && resource.exists() && resource.isFile()) {
|
||||
@@ -121,7 +121,7 @@ public class DevToolsHomePropertiesPostProcessor implements EnvironmentPostProce
|
||||
.anyMatch((fileExtension) -> StringUtils.endsWithIgnoreCase(name, fileExtension));
|
||||
}
|
||||
|
||||
protected File getHomeFolder() {
|
||||
protected File getHomeDirectory() {
|
||||
String home = System.getProperty("user.home");
|
||||
if (StringUtils.hasLength(home)) {
|
||||
return new File(home);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -30,7 +30,7 @@ import org.springframework.util.StringUtils;
|
||||
*/
|
||||
public final class ChangedFile {
|
||||
|
||||
private final File sourceFolder;
|
||||
private final File sourceDirectory;
|
||||
|
||||
private final File file;
|
||||
|
||||
@@ -38,15 +38,15 @@ public final class ChangedFile {
|
||||
|
||||
/**
|
||||
* Create a new {@link ChangedFile} instance.
|
||||
* @param sourceFolder the source folder
|
||||
* @param sourceDirectory the source directory
|
||||
* @param file the file
|
||||
* @param type the type of change
|
||||
*/
|
||||
public ChangedFile(File sourceFolder, File file, Type type) {
|
||||
Assert.notNull(sourceFolder, "SourceFolder must not be null");
|
||||
public ChangedFile(File sourceDirectory, File file, Type type) {
|
||||
Assert.notNull(sourceDirectory, "SourceDirectory must not be null");
|
||||
Assert.notNull(file, "File must not be null");
|
||||
Assert.notNull(type, "Type must not be null");
|
||||
this.sourceFolder = sourceFolder;
|
||||
this.sourceDirectory = sourceDirectory;
|
||||
this.file = file;
|
||||
this.type = type;
|
||||
}
|
||||
@@ -68,17 +68,17 @@ public final class ChangedFile {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of the file relative to the source folder.
|
||||
* Return the name of the file relative to the source directory.
|
||||
* @return the relative name
|
||||
*/
|
||||
public String getRelativeName() {
|
||||
File folder = this.sourceFolder.getAbsoluteFile();
|
||||
File directory = this.sourceDirectory.getAbsoluteFile();
|
||||
File file = this.file.getAbsoluteFile();
|
||||
String folderName = StringUtils.cleanPath(folder.getPath());
|
||||
String directoryName = StringUtils.cleanPath(directory.getPath());
|
||||
String fileName = StringUtils.cleanPath(file.getPath());
|
||||
Assert.state(fileName.startsWith(folderName),
|
||||
() -> "The file " + fileName + " is not contained in the source folder " + folderName);
|
||||
return fileName.substring(folderName.length() + 1);
|
||||
Assert.state(fileName.startsWith(directoryName),
|
||||
() -> "The file " + fileName + " is not contained in the source directory " + directoryName);
|
||||
return fileName.substring(directoryName.length() + 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -22,7 +22,7 @@ import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* A collections of files from a specific source folder that have changed.
|
||||
* A collections of files from a specific source directory that have changed.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @since 1.3.0
|
||||
@@ -31,21 +31,21 @@ import java.util.Set;
|
||||
*/
|
||||
public final class ChangedFiles implements Iterable<ChangedFile> {
|
||||
|
||||
private final File sourceFolder;
|
||||
private final File sourceDirectory;
|
||||
|
||||
private final Set<ChangedFile> files;
|
||||
|
||||
public ChangedFiles(File sourceFolder, Set<ChangedFile> files) {
|
||||
this.sourceFolder = sourceFolder;
|
||||
public ChangedFiles(File sourceDirectory, Set<ChangedFile> files) {
|
||||
this.sourceDirectory = sourceDirectory;
|
||||
this.files = Collections.unmodifiableSet(files);
|
||||
}
|
||||
|
||||
/**
|
||||
* The source folder being watched.
|
||||
* @return the source folder
|
||||
* The source directory being watched.
|
||||
* @return the source directory
|
||||
*/
|
||||
public File getSourceFolder() {
|
||||
return this.sourceFolder;
|
||||
public File getSourceDirectory() {
|
||||
return this.sourceDirectory;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -71,7 +71,7 @@ public final class ChangedFiles implements Iterable<ChangedFile> {
|
||||
}
|
||||
if (obj instanceof ChangedFiles) {
|
||||
ChangedFiles other = (ChangedFiles) obj;
|
||||
return this.sourceFolder.equals(other.sourceFolder) && this.files.equals(other.files);
|
||||
return this.sourceDirectory.equals(other.sourceDirectory) && this.files.equals(other.files);
|
||||
}
|
||||
return super.equals(obj);
|
||||
}
|
||||
@@ -83,7 +83,7 @@ public final class ChangedFiles implements Iterable<ChangedFile> {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.sourceFolder + " " + this.files;
|
||||
return this.sourceDirectory + " " + this.files;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -31,31 +31,31 @@ import org.springframework.boot.devtools.filewatch.ChangedFile.Type;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* A snapshot of a folder at a given point in time.
|
||||
* A snapshot of a directory at a given point in time.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class FolderSnapshot {
|
||||
class DirectorySnapshot {
|
||||
|
||||
private static final Set<String> DOT_FOLDERS = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(".", "..")));
|
||||
private static final Set<String> DOTS = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(".", "..")));
|
||||
|
||||
private final File folder;
|
||||
private final File directory;
|
||||
|
||||
private final Date time;
|
||||
|
||||
private Set<FileSnapshot> files;
|
||||
|
||||
/**
|
||||
* Create a new {@link FolderSnapshot} for the given folder.
|
||||
* @param folder the source folder
|
||||
* Create a new {@link DirectorySnapshot} for the given directory.
|
||||
* @param directory the source directory
|
||||
*/
|
||||
FolderSnapshot(File folder) {
|
||||
Assert.notNull(folder, "Folder must not be null");
|
||||
Assert.isTrue(!folder.isFile(), () -> "Folder '" + folder + "' must not be a file");
|
||||
this.folder = folder;
|
||||
DirectorySnapshot(File directory) {
|
||||
Assert.notNull(directory, "Directory must not be null");
|
||||
Assert.isTrue(!directory.isFile(), () -> "Directory '" + directory + "' must not be a file");
|
||||
this.directory = directory;
|
||||
this.time = new Date();
|
||||
Set<FileSnapshot> files = new LinkedHashSet<>();
|
||||
collectFiles(folder, files);
|
||||
collectFiles(directory, files);
|
||||
this.files = Collections.unmodifiableSet(files);
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ class FolderSnapshot {
|
||||
File[] children = source.listFiles();
|
||||
if (children != null) {
|
||||
for (File child : children) {
|
||||
if (child.isDirectory() && !DOT_FOLDERS.contains(child.getName())) {
|
||||
if (child.isDirectory() && !DOTS.contains(child.getName())) {
|
||||
collectFiles(child, result);
|
||||
}
|
||||
else if (child.isFile()) {
|
||||
@@ -73,29 +73,30 @@ class FolderSnapshot {
|
||||
}
|
||||
}
|
||||
|
||||
ChangedFiles getChangedFiles(FolderSnapshot snapshot, FileFilter triggerFilter) {
|
||||
ChangedFiles getChangedFiles(DirectorySnapshot snapshot, FileFilter triggerFilter) {
|
||||
Assert.notNull(snapshot, "Snapshot must not be null");
|
||||
File folder = this.folder;
|
||||
Assert.isTrue(snapshot.folder.equals(folder), () -> "Snapshot source folder must be '" + folder + "'");
|
||||
File directory = this.directory;
|
||||
Assert.isTrue(snapshot.directory.equals(directory),
|
||||
() -> "Snapshot source directory must be '" + directory + "'");
|
||||
Set<ChangedFile> changes = new LinkedHashSet<>();
|
||||
Map<File, FileSnapshot> previousFiles = getFilesMap();
|
||||
for (FileSnapshot currentFile : snapshot.files) {
|
||||
if (acceptChangedFile(triggerFilter, currentFile)) {
|
||||
FileSnapshot previousFile = previousFiles.remove(currentFile.getFile());
|
||||
if (previousFile == null) {
|
||||
changes.add(new ChangedFile(folder, currentFile.getFile(), Type.ADD));
|
||||
changes.add(new ChangedFile(directory, currentFile.getFile(), Type.ADD));
|
||||
}
|
||||
else if (!previousFile.equals(currentFile)) {
|
||||
changes.add(new ChangedFile(folder, currentFile.getFile(), Type.MODIFY));
|
||||
changes.add(new ChangedFile(directory, currentFile.getFile(), Type.MODIFY));
|
||||
}
|
||||
}
|
||||
}
|
||||
for (FileSnapshot previousFile : previousFiles.values()) {
|
||||
if (acceptChangedFile(triggerFilter, previousFile)) {
|
||||
changes.add(new ChangedFile(folder, previousFile.getFile(), Type.DELETE));
|
||||
changes.add(new ChangedFile(directory, previousFile.getFile(), Type.DELETE));
|
||||
}
|
||||
}
|
||||
return new ChangedFiles(folder, changes);
|
||||
return new ChangedFiles(directory, changes);
|
||||
}
|
||||
|
||||
private boolean acceptChangedFile(FileFilter triggerFilter, FileSnapshot file) {
|
||||
@@ -118,14 +119,14 @@ class FolderSnapshot {
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (obj instanceof FolderSnapshot) {
|
||||
return equals((FolderSnapshot) obj, null);
|
||||
if (obj instanceof DirectorySnapshot) {
|
||||
return equals((DirectorySnapshot) obj, null);
|
||||
}
|
||||
return super.equals(obj);
|
||||
}
|
||||
|
||||
boolean equals(FolderSnapshot other, FileFilter filter) {
|
||||
if (this.folder.equals(other.folder)) {
|
||||
boolean equals(DirectorySnapshot other, FileFilter filter) {
|
||||
if (this.directory.equals(other.directory)) {
|
||||
Set<FileSnapshot> ourFiles = filter(this.files, filter);
|
||||
Set<FileSnapshot> otherFiles = filter(other.files, filter);
|
||||
return ourFiles.equals(otherFiles);
|
||||
@@ -148,22 +149,22 @@ class FolderSnapshot {
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hashCode = this.folder.hashCode();
|
||||
int hashCode = this.directory.hashCode();
|
||||
hashCode = 31 * hashCode + this.files.hashCode();
|
||||
return hashCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the source folder of this snapshot.
|
||||
* @return the source folder
|
||||
* Return the source directory of this snapshot.
|
||||
* @return the source directory
|
||||
*/
|
||||
File getFolder() {
|
||||
return this.folder;
|
||||
File getDirectory() {
|
||||
return this.directory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.folder + " snapshot at " + this.time;
|
||||
return this.directory + " snapshot at " + this.time;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -37,7 +37,7 @@ class FileSnapshot {
|
||||
|
||||
FileSnapshot(File file) {
|
||||
Assert.notNull(file, "File must not be null");
|
||||
Assert.isTrue(file.isFile() || !file.exists(), "File must not be a folder");
|
||||
Assert.isTrue(file.isFile() || !file.exists(), "File must not be a directory");
|
||||
this.file = file;
|
||||
this.exists = file.exists();
|
||||
this.length = file.length();
|
||||
|
||||
@@ -33,7 +33,7 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Watches specific folders for file changes.
|
||||
* Watches specific directories for file changes.
|
||||
*
|
||||
* @author Andy Clement
|
||||
* @author Phillip Webb
|
||||
@@ -56,7 +56,7 @@ public class FileSystemWatcher {
|
||||
|
||||
private final AtomicInteger remainingScans = new AtomicInteger(-1);
|
||||
|
||||
private final Map<File, FolderSnapshot> folders = new HashMap<>();
|
||||
private final Map<File, DirectorySnapshot> directories = new HashMap<>();
|
||||
|
||||
private Thread watchThread;
|
||||
|
||||
@@ -104,30 +104,28 @@ public class FileSystemWatcher {
|
||||
}
|
||||
|
||||
/**
|
||||
* Add source folders to monitor. Cannot be called after the watcher has been
|
||||
* Add source directories to monitor. Cannot be called after the watcher has been
|
||||
* {@link #start() started}.
|
||||
* @param folders the folders to monitor
|
||||
* @param directories the directories to monitor
|
||||
*/
|
||||
public void addSourceFolders(Iterable<File> folders) {
|
||||
Assert.notNull(folders, "Folders must not be null");
|
||||
public void addSourceDirectories(Iterable<File> directories) {
|
||||
Assert.notNull(directories, "Directories must not be null");
|
||||
synchronized (this.monitor) {
|
||||
for (File folder : folders) {
|
||||
addSourceFolder(folder);
|
||||
}
|
||||
directories.forEach(this::addSourceDirectory);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a source folder to monitor. Cannot be called after the watcher has been
|
||||
* Add a source directory to monitor. Cannot be called after the watcher has been
|
||||
* {@link #start() started}.
|
||||
* @param folder the folder to monitor
|
||||
* @param directory the directory to monitor
|
||||
*/
|
||||
public void addSourceFolder(File folder) {
|
||||
Assert.notNull(folder, "Folder must not be null");
|
||||
Assert.isTrue(!folder.isFile(), () -> "Folder '" + folder + "' must not be a file");
|
||||
public void addSourceDirectory(File directory) {
|
||||
Assert.notNull(directory, "Directory must not be null");
|
||||
Assert.isTrue(!directory.isFile(), () -> "Directory '" + directory + "' must not be a file");
|
||||
synchronized (this.monitor) {
|
||||
checkNotStarted();
|
||||
this.folders.put(folder, null);
|
||||
this.directories.put(directory, null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,15 +146,15 @@ public class FileSystemWatcher {
|
||||
}
|
||||
|
||||
/**
|
||||
* Start monitoring the source folder for changes.
|
||||
* Start monitoring the source directory for changes.
|
||||
*/
|
||||
public void start() {
|
||||
synchronized (this.monitor) {
|
||||
saveInitialSnapshots();
|
||||
if (this.watchThread == null) {
|
||||
Map<File, FolderSnapshot> localFolders = new HashMap<>(this.folders);
|
||||
Map<File, DirectorySnapshot> localDirectories = new HashMap<>(this.directories);
|
||||
this.watchThread = new Thread(new Watcher(this.remainingScans, new ArrayList<>(this.listeners),
|
||||
this.triggerFilter, this.pollInterval, this.quietPeriod, localFolders));
|
||||
this.triggerFilter, this.pollInterval, this.quietPeriod, localDirectories));
|
||||
this.watchThread.setName("File Watcher");
|
||||
this.watchThread.setDaemon(this.daemon);
|
||||
this.watchThread.start();
|
||||
@@ -165,18 +163,18 @@ public class FileSystemWatcher {
|
||||
}
|
||||
|
||||
private void saveInitialSnapshots() {
|
||||
this.folders.replaceAll((f, v) -> new FolderSnapshot(f));
|
||||
this.directories.replaceAll((f, v) -> new DirectorySnapshot(f));
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop monitoring the source folders.
|
||||
* Stop monitoring the source directories.
|
||||
*/
|
||||
public void stop() {
|
||||
stopAfter(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop monitoring the source folders.
|
||||
* Stop monitoring the source directories.
|
||||
* @param remainingScans the number of remaining scans
|
||||
*/
|
||||
void stopAfter(int remainingScans) {
|
||||
@@ -213,16 +211,16 @@ public class FileSystemWatcher {
|
||||
|
||||
private final long quietPeriod;
|
||||
|
||||
private Map<File, FolderSnapshot> folders;
|
||||
private Map<File, DirectorySnapshot> directories;
|
||||
|
||||
private Watcher(AtomicInteger remainingScans, List<FileChangeListener> listeners, FileFilter triggerFilter,
|
||||
long pollInterval, long quietPeriod, Map<File, FolderSnapshot> folders) {
|
||||
long pollInterval, long quietPeriod, Map<File, DirectorySnapshot> directories) {
|
||||
this.remainingScans = remainingScans;
|
||||
this.listeners = listeners;
|
||||
this.triggerFilter = triggerFilter;
|
||||
this.pollInterval = pollInterval;
|
||||
this.quietPeriod = quietPeriod;
|
||||
this.folders = folders;
|
||||
this.directories = directories;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -244,47 +242,47 @@ public class FileSystemWatcher {
|
||||
|
||||
private void scan() throws InterruptedException {
|
||||
Thread.sleep(this.pollInterval - this.quietPeriod);
|
||||
Map<File, FolderSnapshot> previous;
|
||||
Map<File, FolderSnapshot> current = this.folders;
|
||||
Map<File, DirectorySnapshot> previous;
|
||||
Map<File, DirectorySnapshot> current = this.directories;
|
||||
do {
|
||||
previous = current;
|
||||
current = getCurrentSnapshots();
|
||||
Thread.sleep(this.quietPeriod);
|
||||
}
|
||||
while (isDifferent(previous, current));
|
||||
if (isDifferent(this.folders, current)) {
|
||||
if (isDifferent(this.directories, current)) {
|
||||
updateSnapshots(current.values());
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isDifferent(Map<File, FolderSnapshot> previous, Map<File, FolderSnapshot> current) {
|
||||
private boolean isDifferent(Map<File, DirectorySnapshot> previous, Map<File, DirectorySnapshot> current) {
|
||||
if (!previous.keySet().equals(current.keySet())) {
|
||||
return true;
|
||||
}
|
||||
for (Map.Entry<File, FolderSnapshot> entry : previous.entrySet()) {
|
||||
FolderSnapshot previousFolder = entry.getValue();
|
||||
FolderSnapshot currentFolder = current.get(entry.getKey());
|
||||
if (!previousFolder.equals(currentFolder, this.triggerFilter)) {
|
||||
for (Map.Entry<File, DirectorySnapshot> entry : previous.entrySet()) {
|
||||
DirectorySnapshot previousDirectory = entry.getValue();
|
||||
DirectorySnapshot currentDirectory = current.get(entry.getKey());
|
||||
if (!previousDirectory.equals(currentDirectory, this.triggerFilter)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private Map<File, FolderSnapshot> getCurrentSnapshots() {
|
||||
Map<File, FolderSnapshot> snapshots = new LinkedHashMap<>();
|
||||
for (File folder : this.folders.keySet()) {
|
||||
snapshots.put(folder, new FolderSnapshot(folder));
|
||||
private Map<File, DirectorySnapshot> getCurrentSnapshots() {
|
||||
Map<File, DirectorySnapshot> snapshots = new LinkedHashMap<>();
|
||||
for (File directory : this.directories.keySet()) {
|
||||
snapshots.put(directory, new DirectorySnapshot(directory));
|
||||
}
|
||||
return snapshots;
|
||||
}
|
||||
|
||||
private void updateSnapshots(Collection<FolderSnapshot> snapshots) {
|
||||
Map<File, FolderSnapshot> updated = new LinkedHashMap<>();
|
||||
private void updateSnapshots(Collection<DirectorySnapshot> snapshots) {
|
||||
Map<File, DirectorySnapshot> updated = new LinkedHashMap<>();
|
||||
Set<ChangedFiles> changeSet = new LinkedHashSet<>();
|
||||
for (FolderSnapshot snapshot : snapshots) {
|
||||
FolderSnapshot previous = this.folders.get(snapshot.getFolder());
|
||||
updated.put(snapshot.getFolder(), snapshot);
|
||||
for (DirectorySnapshot snapshot : snapshots) {
|
||||
DirectorySnapshot previous = this.directories.get(snapshot.getDirectory());
|
||||
updated.put(snapshot.getDirectory(), snapshot);
|
||||
ChangedFiles changedFiles = previous.getChangedFiles(snapshot, this.triggerFilter);
|
||||
if (!changedFiles.getFiles().isEmpty()) {
|
||||
changeSet.add(changedFiles);
|
||||
@@ -293,7 +291,7 @@ public class FileSystemWatcher {
|
||||
if (!changeSet.isEmpty()) {
|
||||
fireListeners(Collections.unmodifiableSet(changeSet));
|
||||
}
|
||||
this.folders = updated;
|
||||
this.directories = updated;
|
||||
}
|
||||
|
||||
private void fireListeners(Set<ChangedFiles> changeSet) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -144,9 +144,9 @@ public class ClassPathChangeUploader implements ApplicationListener<ClassPathCha
|
||||
private ClassLoaderFiles getClassLoaderFiles(ClassPathChangedEvent event) throws IOException {
|
||||
ClassLoaderFiles files = new ClassLoaderFiles();
|
||||
for (ChangedFiles changedFiles : event.getChangeSet()) {
|
||||
String sourceFolder = changedFiles.getSourceFolder().getAbsolutePath();
|
||||
String sourceDirectory = changedFiles.getSourceDirectory().getAbsolutePath();
|
||||
for (ChangedFile changedFile : changedFiles) {
|
||||
files.addFile(sourceFolder, changedFile.getRelativeName(), asClassLoaderFile(changedFile));
|
||||
files.addFile(sourceDirectory, changedFile.getRelativeName(), asClassLoaderFile(changedFile));
|
||||
}
|
||||
}
|
||||
return files;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -56,7 +56,7 @@ final class ChangeableUrls implements Iterable<URL> {
|
||||
DevToolsSettings settings = DevToolsSettings.get();
|
||||
List<URL> reloadableUrls = new ArrayList<>(urls.length);
|
||||
for (URL url : urls) {
|
||||
if ((settings.isRestartInclude(url) || isFolderUrl(url.toString())) && !settings.isRestartExclude(url)) {
|
||||
if ((settings.isRestartInclude(url) || isDirectoryUrl(url.toString())) && !settings.isRestartExclude(url)) {
|
||||
reloadableUrls.add(url);
|
||||
}
|
||||
}
|
||||
@@ -66,7 +66,7 @@ final class ChangeableUrls implements Iterable<URL> {
|
||||
this.urls = Collections.unmodifiableList(reloadableUrls);
|
||||
}
|
||||
|
||||
private boolean isFolderUrl(String urlString) {
|
||||
private boolean isDirectoryUrl(String urlString) {
|
||||
return urlString.startsWith("file:") && urlString.endsWith("/");
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ import org.springframework.boot.devtools.restart.classloader.ClassLoaderFile;
|
||||
import org.springframework.boot.devtools.restart.classloader.ClassLoaderFile.Kind;
|
||||
import org.springframework.boot.devtools.restart.classloader.ClassLoaderFileURLStreamHandler;
|
||||
import org.springframework.boot.devtools.restart.classloader.ClassLoaderFiles;
|
||||
import org.springframework.boot.devtools.restart.classloader.ClassLoaderFiles.SourceFolder;
|
||||
import org.springframework.boot.devtools.restart.classloader.ClassLoaderFiles.SourceDirectory;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.support.AbstractApplicationContext;
|
||||
import org.springframework.core.io.AbstractResource;
|
||||
@@ -123,8 +123,8 @@ final class ClassLoaderFilesResourcePatternResolver implements ResourcePatternRe
|
||||
private List<Resource> getAdditionalResources(String locationPattern) throws MalformedURLException {
|
||||
List<Resource> additionalResources = new ArrayList<>();
|
||||
String trimmedLocationPattern = trimLocationPattern(locationPattern);
|
||||
for (SourceFolder sourceFolder : this.classLoaderFiles.getSourceFolders()) {
|
||||
for (Entry<String, ClassLoaderFile> entry : sourceFolder.getFilesEntrySet()) {
|
||||
for (SourceDirectory sourceDirectory : this.classLoaderFiles.getSourceDirectories()) {
|
||||
for (Entry<String, ClassLoaderFile> entry : sourceDirectory.getFilesEntrySet()) {
|
||||
String name = entry.getKey();
|
||||
ClassLoaderFile file = entry.getValue();
|
||||
if (file.getKind() != Kind.DELETED && this.antPathMatcher.match(trimmedLocationPattern, name)) {
|
||||
@@ -147,8 +147,8 @@ final class ClassLoaderFilesResourcePatternResolver implements ResourcePatternRe
|
||||
}
|
||||
|
||||
private boolean isDeleted(Resource resource) {
|
||||
for (SourceFolder sourceFolder : this.classLoaderFiles.getSourceFolders()) {
|
||||
for (Entry<String, ClassLoaderFile> entry : sourceFolder.getFilesEntrySet()) {
|
||||
for (SourceDirectory sourceDirectory : this.classLoaderFiles.getSourceDirectories()) {
|
||||
for (Entry<String, ClassLoaderFile> entry : sourceDirectory.getFilesEntrySet()) {
|
||||
try {
|
||||
String name = entry.getKey();
|
||||
ClassLoaderFile file = entry.getValue();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -30,7 +30,7 @@ import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* {@link ClassLoaderFileRepository} that maintains a collection of
|
||||
* {@link ClassLoaderFile} items grouped by source folders.
|
||||
* {@link ClassLoaderFile} items grouped by source directories.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @since 1.3.0
|
||||
@@ -41,13 +41,13 @@ public class ClassLoaderFiles implements ClassLoaderFileRepository, Serializable
|
||||
|
||||
private static final long serialVersionUID = 1;
|
||||
|
||||
private final Map<String, SourceFolder> sourceFolders;
|
||||
private final Map<String, SourceDirectory> sourceDirectories;
|
||||
|
||||
/**
|
||||
* Create a new {@link ClassLoaderFiles} instance.
|
||||
*/
|
||||
public ClassLoaderFiles() {
|
||||
this.sourceFolders = new LinkedHashMap<>();
|
||||
this.sourceDirectories = new LinkedHashMap<>();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -56,7 +56,7 @@ public class ClassLoaderFiles implements ClassLoaderFileRepository, Serializable
|
||||
*/
|
||||
public ClassLoaderFiles(ClassLoaderFiles classLoaderFiles) {
|
||||
Assert.notNull(classLoaderFiles, "ClassLoaderFiles must not be null");
|
||||
this.sourceFolders = new LinkedHashMap<>(classLoaderFiles.sourceFolders);
|
||||
this.sourceDirectories = new LinkedHashMap<>(classLoaderFiles.sourceDirectories);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -66,9 +66,9 @@ public class ClassLoaderFiles implements ClassLoaderFileRepository, Serializable
|
||||
*/
|
||||
public void addAll(ClassLoaderFiles files) {
|
||||
Assert.notNull(files, "Files must not be null");
|
||||
for (SourceFolder folder : files.getSourceFolders()) {
|
||||
for (Map.Entry<String, ClassLoaderFile> entry : folder.getFilesEntrySet()) {
|
||||
addFile(folder.getName(), entry.getKey(), entry.getValue());
|
||||
for (SourceDirectory directory : files.getSourceDirectories()) {
|
||||
for (Map.Entry<String, ClassLoaderFile> entry : directory.getFilesEntrySet()) {
|
||||
addFile(directory.getName(), entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -84,45 +84,45 @@ public class ClassLoaderFiles implements ClassLoaderFileRepository, Serializable
|
||||
|
||||
/**
|
||||
* Add a single {@link ClassLoaderFile} to the collection.
|
||||
* @param sourceFolder the source folder of the file
|
||||
* @param sourceDirectory the source directory of the file
|
||||
* @param name the name of the file
|
||||
* @param file the file to add
|
||||
*/
|
||||
public void addFile(String sourceFolder, String name, ClassLoaderFile file) {
|
||||
Assert.notNull(sourceFolder, "SourceFolder must not be null");
|
||||
public void addFile(String sourceDirectory, String name, ClassLoaderFile file) {
|
||||
Assert.notNull(sourceDirectory, "SourceDirectory must not be null");
|
||||
Assert.notNull(name, "Name must not be null");
|
||||
Assert.notNull(file, "File must not be null");
|
||||
removeAll(name);
|
||||
getOrCreateSourceFolder(sourceFolder).add(name, file);
|
||||
getOrCreateSourceDirectory(sourceDirectory).add(name, file);
|
||||
}
|
||||
|
||||
private void removeAll(String name) {
|
||||
for (SourceFolder sourceFolder : this.sourceFolders.values()) {
|
||||
sourceFolder.remove(name);
|
||||
for (SourceDirectory sourceDirectory : this.sourceDirectories.values()) {
|
||||
sourceDirectory.remove(name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get or create a {@link SourceFolder} with the given name.
|
||||
* @param name the name of the folder
|
||||
* @return an existing or newly added {@link SourceFolder}
|
||||
* Get or create a {@link SourceDirectory} with the given name.
|
||||
* @param name the name of the directory
|
||||
* @return an existing or newly added {@link SourceDirectory}
|
||||
*/
|
||||
protected final SourceFolder getOrCreateSourceFolder(String name) {
|
||||
SourceFolder sourceFolder = this.sourceFolders.get(name);
|
||||
if (sourceFolder == null) {
|
||||
sourceFolder = new SourceFolder(name);
|
||||
this.sourceFolders.put(name, sourceFolder);
|
||||
protected final SourceDirectory getOrCreateSourceDirectory(String name) {
|
||||
SourceDirectory sourceDirectory = this.sourceDirectories.get(name);
|
||||
if (sourceDirectory == null) {
|
||||
sourceDirectory = new SourceDirectory(name);
|
||||
this.sourceDirectories.put(name, sourceDirectory);
|
||||
}
|
||||
return sourceFolder;
|
||||
return sourceDirectory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all {@link SourceFolder SourceFolders} that have been added to the
|
||||
* Return all {@link SourceDirectory SourceDirectories} that have been added to the
|
||||
* collection.
|
||||
* @return a collection of {@link SourceFolder} items
|
||||
* @return a collection of {@link SourceDirectory} items
|
||||
*/
|
||||
public Collection<SourceFolder> getSourceFolders() {
|
||||
return Collections.unmodifiableCollection(this.sourceFolders.values());
|
||||
public Collection<SourceDirectory> getSourceDirectories() {
|
||||
return Collections.unmodifiableCollection(this.sourceDirectories.values());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -131,16 +131,16 @@ public class ClassLoaderFiles implements ClassLoaderFileRepository, Serializable
|
||||
*/
|
||||
public int size() {
|
||||
int size = 0;
|
||||
for (SourceFolder sourceFolder : this.sourceFolders.values()) {
|
||||
size += sourceFolder.getFiles().size();
|
||||
for (SourceDirectory sourceDirectory : this.sourceDirectories.values()) {
|
||||
size += sourceDirectory.getFiles().size();
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClassLoaderFile getFile(String name) {
|
||||
for (SourceFolder sourceFolder : this.sourceFolders.values()) {
|
||||
ClassLoaderFile file = sourceFolder.get(name);
|
||||
for (SourceDirectory sourceDirectory : this.sourceDirectories.values()) {
|
||||
ClassLoaderFile file = sourceDirectory.get(name);
|
||||
if (file != null) {
|
||||
return file;
|
||||
}
|
||||
@@ -149,9 +149,9 @@ public class ClassLoaderFiles implements ClassLoaderFileRepository, Serializable
|
||||
}
|
||||
|
||||
/**
|
||||
* An individual source folder that is being managed by the collection.
|
||||
* An individual source directory that is being managed by the collection.
|
||||
*/
|
||||
public static class SourceFolder implements Serializable {
|
||||
public static class SourceDirectory implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1;
|
||||
|
||||
@@ -159,7 +159,7 @@ public class ClassLoaderFiles implements ClassLoaderFileRepository, Serializable
|
||||
|
||||
private final Map<String, ClassLoaderFile> files = new LinkedHashMap<>();
|
||||
|
||||
SourceFolder(String name) {
|
||||
SourceDirectory(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@@ -180,8 +180,8 @@ public class ClassLoaderFiles implements ClassLoaderFileRepository, Serializable
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of the source folder.
|
||||
* @return the name of the source folder
|
||||
* Return the name of the source directory.
|
||||
* @return the name of the source directory
|
||||
*/
|
||||
public String getName() {
|
||||
return this.name;
|
||||
@@ -189,8 +189,8 @@ public class ClassLoaderFiles implements ClassLoaderFileRepository, Serializable
|
||||
|
||||
/**
|
||||
* Return all {@link ClassLoaderFile ClassLoaderFiles} in the collection that are
|
||||
* contained in this source folder.
|
||||
* @return the files contained in the source folder
|
||||
* contained in this source directory.
|
||||
* @return the files contained in the source directory
|
||||
*/
|
||||
public Collection<ClassLoaderFile> getFiles() {
|
||||
return Collections.unmodifiableCollection(this.files.values());
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -26,13 +26,13 @@ import java.util.regex.Pattern;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Default implementation of {@link SourceFolderUrlFilter} that attempts to match URLs
|
||||
* Default implementation of {@link SourceDirectoryUrlFilter} that attempts to match URLs
|
||||
* using common naming conventions.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @since 1.3.0
|
||||
* @since 2.3.0
|
||||
*/
|
||||
public class DefaultSourceFolderUrlFilter implements SourceFolderUrlFilter {
|
||||
public class DefaultSourceDirectoryUrlFilter implements SourceDirectoryUrlFilter {
|
||||
|
||||
private static final String[] COMMON_ENDINGS = { "/target/classes", "/bin" };
|
||||
|
||||
@@ -44,12 +44,12 @@ public class DefaultSourceFolderUrlFilter implements SourceFolderUrlFilter {
|
||||
"spring-boot-devtools", "spring-boot-autoconfigure", "spring-boot-actuator", "spring-boot-starter"));
|
||||
|
||||
@Override
|
||||
public boolean isMatch(String sourceFolder, URL url) {
|
||||
public boolean isMatch(String sourceDirectory, URL url) {
|
||||
String jarName = getJarName(url);
|
||||
if (!StringUtils.hasLength(jarName)) {
|
||||
return false;
|
||||
}
|
||||
return isMatch(sourceFolder, jarName);
|
||||
return isMatch(sourceDirectory, jarName);
|
||||
}
|
||||
|
||||
private String getJarName(URL url) {
|
||||
@@ -60,23 +60,23 @@ public class DefaultSourceFolderUrlFilter implements SourceFolderUrlFilter {
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean isMatch(String sourceFolder, String jarName) {
|
||||
sourceFolder = stripTrailingSlash(sourceFolder);
|
||||
sourceFolder = stripCommonEnds(sourceFolder);
|
||||
String[] folders = StringUtils.delimitedListToStringArray(sourceFolder, "/");
|
||||
for (int i = folders.length - 1; i >= 0; i--) {
|
||||
if (isFolderMatch(folders[i], jarName)) {
|
||||
private boolean isMatch(String sourceDirectory, String jarName) {
|
||||
sourceDirectory = stripTrailingSlash(sourceDirectory);
|
||||
sourceDirectory = stripCommonEnds(sourceDirectory);
|
||||
String[] directories = StringUtils.delimitedListToStringArray(sourceDirectory, "/");
|
||||
for (int i = directories.length - 1; i >= 0; i--) {
|
||||
if (isDirectoryMatch(directories[i], jarName)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isFolderMatch(String folder, String jarName) {
|
||||
if (!jarName.startsWith(folder) || SKIPPED_PROJECTS.contains(folder)) {
|
||||
private boolean isDirectoryMatch(String directory, String jarName) {
|
||||
if (!jarName.startsWith(directory) || SKIPPED_PROJECTS.contains(directory)) {
|
||||
return false;
|
||||
}
|
||||
String version = jarName.substring(folder.length());
|
||||
String version = jarName.substring(directory.length());
|
||||
return version.isEmpty() || VERSION_PATTERN.matcher(version).matches();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -44,12 +44,12 @@ public class HttpRestartServer {
|
||||
|
||||
/**
|
||||
* Create a new {@link HttpRestartServer} instance.
|
||||
* @param sourceFolderUrlFilter the source filter used to link remote folder to the
|
||||
* local classpath
|
||||
* @param sourceDirectoryUrlFilter the source filter used to link remote directory to
|
||||
* the local classpath
|
||||
*/
|
||||
public HttpRestartServer(SourceFolderUrlFilter sourceFolderUrlFilter) {
|
||||
Assert.notNull(sourceFolderUrlFilter, "SourceFolderUrlFilter must not be null");
|
||||
this.server = new RestartServer(sourceFolderUrlFilter);
|
||||
public HttpRestartServer(SourceDirectoryUrlFilter sourceDirectoryUrlFilter) {
|
||||
Assert.notNull(sourceDirectoryUrlFilter, "SourceDirectoryUrlFilter must not be null");
|
||||
this.server = new RestartServer(sourceDirectoryUrlFilter);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -32,7 +32,7 @@ import org.springframework.boot.devtools.restart.Restarter;
|
||||
import org.springframework.boot.devtools.restart.classloader.ClassLoaderFile;
|
||||
import org.springframework.boot.devtools.restart.classloader.ClassLoaderFile.Kind;
|
||||
import org.springframework.boot.devtools.restart.classloader.ClassLoaderFiles;
|
||||
import org.springframework.boot.devtools.restart.classloader.ClassLoaderFiles.SourceFolder;
|
||||
import org.springframework.boot.devtools.restart.classloader.ClassLoaderFiles.SourceDirectory;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
import org.springframework.util.ResourceUtils;
|
||||
@@ -48,29 +48,29 @@ public class RestartServer {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(RestartServer.class);
|
||||
|
||||
private final SourceFolderUrlFilter sourceFolderUrlFilter;
|
||||
private final SourceDirectoryUrlFilter sourceDirectoryUrlFilter;
|
||||
|
||||
private final ClassLoader classLoader;
|
||||
|
||||
/**
|
||||
* Create a new {@link RestartServer} instance.
|
||||
* @param sourceFolderUrlFilter the source filter used to link remote folder to the
|
||||
* local classpath
|
||||
* @param sourceDirectoryUrlFilter the source filter used to link remote directory to
|
||||
* the local classpath
|
||||
*/
|
||||
public RestartServer(SourceFolderUrlFilter sourceFolderUrlFilter) {
|
||||
this(sourceFolderUrlFilter, Thread.currentThread().getContextClassLoader());
|
||||
public RestartServer(SourceDirectoryUrlFilter sourceDirectoryUrlFilter) {
|
||||
this(sourceDirectoryUrlFilter, Thread.currentThread().getContextClassLoader());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@link RestartServer} instance.
|
||||
* @param sourceFolderUrlFilter the source filter used to link remote folder to the
|
||||
* local classpath
|
||||
* @param sourceDirectoryUrlFilter the source filter used to link remote directory to
|
||||
* the local classpath
|
||||
* @param classLoader the application classloader
|
||||
*/
|
||||
public RestartServer(SourceFolderUrlFilter sourceFolderUrlFilter, ClassLoader classLoader) {
|
||||
Assert.notNull(sourceFolderUrlFilter, "SourceFolderUrlFilter must not be null");
|
||||
public RestartServer(SourceDirectoryUrlFilter sourceDirectoryUrlFilter, ClassLoader classLoader) {
|
||||
Assert.notNull(sourceDirectoryUrlFilter, "SourceDirectoryUrlFilter must not be null");
|
||||
Assert.notNull(classLoader, "ClassLoader must not be null");
|
||||
this.sourceFolderUrlFilter = sourceFolderUrlFilter;
|
||||
this.sourceDirectoryUrlFilter = sourceDirectoryUrlFilter;
|
||||
this.classLoader = classLoader;
|
||||
}
|
||||
|
||||
@@ -82,27 +82,27 @@ public class RestartServer {
|
||||
public void updateAndRestart(ClassLoaderFiles files) {
|
||||
Set<URL> urls = new LinkedHashSet<>();
|
||||
Set<URL> classLoaderUrls = getClassLoaderUrls();
|
||||
for (SourceFolder folder : files.getSourceFolders()) {
|
||||
for (Entry<String, ClassLoaderFile> entry : folder.getFilesEntrySet()) {
|
||||
for (SourceDirectory directory : files.getSourceDirectories()) {
|
||||
for (Entry<String, ClassLoaderFile> entry : directory.getFilesEntrySet()) {
|
||||
for (URL url : classLoaderUrls) {
|
||||
if (updateFileSystem(url, entry.getKey(), entry.getValue())) {
|
||||
urls.add(url);
|
||||
}
|
||||
}
|
||||
}
|
||||
urls.addAll(getMatchingUrls(classLoaderUrls, folder.getName()));
|
||||
urls.addAll(getMatchingUrls(classLoaderUrls, directory.getName()));
|
||||
}
|
||||
updateTimeStamp(urls);
|
||||
restart(urls, files);
|
||||
}
|
||||
|
||||
private boolean updateFileSystem(URL url, String name, ClassLoaderFile classLoaderFile) {
|
||||
if (!isFolderUrl(url.toString())) {
|
||||
if (!isDirectoryUrl(url.toString())) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
File folder = ResourceUtils.getFile(url);
|
||||
File file = new File(folder, name);
|
||||
File directory = ResourceUtils.getFile(url);
|
||||
File file = new File(directory, name);
|
||||
if (file.exists() && file.canWrite()) {
|
||||
if (classLoaderFile.getKind() == Kind.DELETED) {
|
||||
return file.delete();
|
||||
@@ -117,16 +117,16 @@ public class RestartServer {
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isFolderUrl(String urlString) {
|
||||
private boolean isDirectoryUrl(String urlString) {
|
||||
return urlString.startsWith("file:") && urlString.endsWith("/");
|
||||
}
|
||||
|
||||
private Set<URL> getMatchingUrls(Set<URL> urls, String sourceFolder) {
|
||||
private Set<URL> getMatchingUrls(Set<URL> urls, String sourceDirectory) {
|
||||
Set<URL> matchingUrls = new LinkedHashSet<>();
|
||||
for (URL url : urls) {
|
||||
if (this.sourceFolderUrlFilter.isMatch(sourceFolder, url)) {
|
||||
if (this.sourceDirectoryUrlFilter.isMatch(sourceDirectory, url)) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("URL " + url + " matched against source folder " + sourceFolder);
|
||||
logger.debug("URL " + url + " matched against source directory " + sourceDirectory);
|
||||
}
|
||||
matchingUrls.add(url);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,22 +19,22 @@ package org.springframework.boot.devtools.restart.server;
|
||||
import java.net.URL;
|
||||
|
||||
/**
|
||||
* Filter URLs based on a source folder name. Used to match URLs from the running
|
||||
* classpath against source folders on a remote system.
|
||||
* Filter URLs based on a source directory name. Used to match URLs from the running
|
||||
* classpath against source directory on a remote system.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @since 1.3.0
|
||||
* @see DefaultSourceFolderUrlFilter
|
||||
* @since 2.3.0
|
||||
* @see DefaultSourceDirectoryUrlFilter
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface SourceFolderUrlFilter {
|
||||
public interface SourceDirectoryUrlFilter {
|
||||
|
||||
/**
|
||||
* Determine if the specified URL matches a source folder.
|
||||
* @param sourceFolder the source folder
|
||||
* Determine if the specified URL matches a source directory.
|
||||
* @param sourceDirectory the source directory
|
||||
* @param url the URL to check
|
||||
* @return {@code true} if the URL matches
|
||||
*/
|
||||
boolean isMatch(String sourceFolder, URL url);
|
||||
boolean isMatch(String sourceDirectory, URL url);
|
||||
|
||||
}
|
||||
@@ -213,8 +213,8 @@ class LocalDevToolsAutoConfigurationTests {
|
||||
ClassPathFileSystemWatcher classPathWatcher = this.context.getBean(ClassPathFileSystemWatcher.class);
|
||||
Object watcher = ReflectionTestUtils.getField(classPathWatcher, "fileSystemWatcher");
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<File, Object> folders = (Map<File, Object>) ReflectionTestUtils.getField(watcher, "folders");
|
||||
assertThat(folders).hasSize(2).containsKey(new File("src/main/java").getAbsoluteFile())
|
||||
Map<File, Object> directories = (Map<File, Object>) ReflectionTestUtils.getField(watcher, "directories");
|
||||
assertThat(directories).hasSize(2).containsKey(new File("src/main/java").getAbsoluteFile())
|
||||
.containsKey(new File("src/test/java").getAbsoluteFile());
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -32,7 +32,7 @@ import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfi
|
||||
import org.springframework.boot.devtools.remote.server.DispatcherFilter;
|
||||
import org.springframework.boot.devtools.restart.MockRestarter;
|
||||
import org.springframework.boot.devtools.restart.server.HttpRestartServer;
|
||||
import org.springframework.boot.devtools.restart.server.SourceFolderUrlFilter;
|
||||
import org.springframework.boot.devtools.restart.server.SourceDirectoryUrlFilter;
|
||||
import org.springframework.boot.test.util.TestPropertyValues;
|
||||
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
@@ -244,8 +244,8 @@ class RemoteDevToolsAutoConfigurationTests {
|
||||
|
||||
@Bean
|
||||
HttpRestartServer remoteRestartHttpRestartServer() {
|
||||
SourceFolderUrlFilter sourceFolderUrlFilter = mock(SourceFolderUrlFilter.class);
|
||||
return new MockHttpRestartServer(sourceFolderUrlFilter);
|
||||
SourceDirectoryUrlFilter sourceDirectoryUrlFilter = mock(SourceDirectoryUrlFilter.class);
|
||||
return new MockHttpRestartServer(sourceDirectoryUrlFilter);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -257,8 +257,8 @@ class RemoteDevToolsAutoConfigurationTests {
|
||||
|
||||
private boolean invoked;
|
||||
|
||||
MockHttpRestartServer(SourceFolderUrlFilter sourceFolderUrlFilter) {
|
||||
super(sourceFolderUrlFilter);
|
||||
MockHttpRestartServer(SourceDirectoryUrlFilter sourceDirectoryUrlFilter) {
|
||||
super(sourceDirectoryUrlFilter);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -93,10 +93,10 @@ class ClassPathFileChangeListenerTests {
|
||||
private void testSendsEvent(boolean restart) {
|
||||
ClassPathFileChangeListener listener = new ClassPathFileChangeListener(this.eventPublisher,
|
||||
this.restartStrategy, this.fileSystemWatcher);
|
||||
File folder = new File("s1");
|
||||
File directory = new File("s1");
|
||||
File file = new File("f1");
|
||||
ChangedFile file1 = new ChangedFile(folder, file, ChangedFile.Type.ADD);
|
||||
ChangedFile file2 = new ChangedFile(folder, file, ChangedFile.Type.ADD);
|
||||
ChangedFile file1 = new ChangedFile(directory, file, ChangedFile.Type.ADD);
|
||||
ChangedFile file2 = new ChangedFile(directory, file, ChangedFile.Type.ADD);
|
||||
Set<ChangedFile> files = new LinkedHashSet<>();
|
||||
files.add(file1);
|
||||
files.add(file2);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -57,19 +57,19 @@ class ClassPathFileSystemWatcherTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void configuredWithRestartStrategy(@TempDir File folder) throws Exception {
|
||||
void configuredWithRestartStrategy(@TempDir File directory) throws Exception {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
|
||||
Map<String, Object> properties = new HashMap<>();
|
||||
List<URL> urls = new ArrayList<>();
|
||||
urls.add(new URL("https://spring.io"));
|
||||
urls.add(folder.toURI().toURL());
|
||||
urls.add(directory.toURI().toURL());
|
||||
properties.put("urls", urls);
|
||||
MapPropertySource propertySource = new MapPropertySource("test", properties);
|
||||
context.getEnvironment().getPropertySources().addLast(propertySource);
|
||||
context.register(Config.class);
|
||||
context.refresh();
|
||||
Thread.sleep(200);
|
||||
File classFile = new File(folder, "Example.class");
|
||||
File classFile = new File(directory, "Example.class");
|
||||
FileCopyUtils.copy("file".getBytes(), classFile);
|
||||
Thread.sleep(1000);
|
||||
List<ClassPathChangedEvent> events = context.getBean(Listener.class).getEvents();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -49,29 +49,29 @@ class PatternClassPathRestartStrategyTests {
|
||||
void singlePattern() {
|
||||
ClassPathRestartStrategy strategy = createStrategy("static/**");
|
||||
assertRestartRequired(strategy, "static/file.txt", false);
|
||||
assertRestartRequired(strategy, "static/folder/file.txt", false);
|
||||
assertRestartRequired(strategy, "static/directory/file.txt", false);
|
||||
assertRestartRequired(strategy, "public/file.txt", true);
|
||||
assertRestartRequired(strategy, "public/folder/file.txt", true);
|
||||
assertRestartRequired(strategy, "public/directory/file.txt", true);
|
||||
}
|
||||
|
||||
@Test
|
||||
void multiplePatterns() {
|
||||
ClassPathRestartStrategy strategy = createStrategy("static/**,public/**");
|
||||
assertRestartRequired(strategy, "static/file.txt", false);
|
||||
assertRestartRequired(strategy, "static/folder/file.txt", false);
|
||||
assertRestartRequired(strategy, "static/directory/file.txt", false);
|
||||
assertRestartRequired(strategy, "public/file.txt", false);
|
||||
assertRestartRequired(strategy, "public/folder/file.txt", false);
|
||||
assertRestartRequired(strategy, "public/directory/file.txt", false);
|
||||
assertRestartRequired(strategy, "src/file.txt", true);
|
||||
assertRestartRequired(strategy, "src/folder/file.txt", true);
|
||||
assertRestartRequired(strategy, "src/directory/file.txt", true);
|
||||
}
|
||||
|
||||
@Test
|
||||
void pomChange() {
|
||||
ClassPathRestartStrategy strategy = createStrategy("META-INF/maven/**");
|
||||
assertRestartRequired(strategy, "pom.xml", true);
|
||||
String mavenFolder = "META-INF/maven/org.springframework.boot/spring-boot-devtools";
|
||||
assertRestartRequired(strategy, mavenFolder + "/pom.xml", false);
|
||||
assertRestartRequired(strategy, mavenFolder + "/pom.properties", false);
|
||||
String mavenDirectory = "META-INF/maven/org.springframework.boot/spring-boot-devtools";
|
||||
assertRestartRequired(strategy, mavenDirectory + "/pom.xml", false);
|
||||
assertRestartRequired(strategy, mavenDirectory + "/pom.properties", false);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -55,7 +55,7 @@ class DevToolsHomePropertiesPostProcessorTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void loadsPropertiesFromHomeFolderUsingProperties() throws Exception {
|
||||
void loadsPropertiesFromHomeDirectoryUsingProperties() throws Exception {
|
||||
Properties properties = new Properties();
|
||||
properties.put("abc", "def");
|
||||
writeFile(properties, ".spring-boot-devtools.properties");
|
||||
@@ -64,7 +64,7 @@ class DevToolsHomePropertiesPostProcessorTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void loadsPropertiesFromConfigFolderUsingProperties() throws Exception {
|
||||
void loadsPropertiesFromConfigDirectoryUsingProperties() throws Exception {
|
||||
Properties properties = new Properties();
|
||||
properties.put("abc", "def");
|
||||
OutputStream out = new FileOutputStream(new File(this.configDir, "spring-boot-devtools.properties"));
|
||||
@@ -75,7 +75,7 @@ class DevToolsHomePropertiesPostProcessorTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void loadsPropertiesFromConfigFolderUsingYml() throws Exception {
|
||||
void loadsPropertiesFromConfigDirectoryUsingYml() throws Exception {
|
||||
OutputStream out = new FileOutputStream(new File(this.configDir, "spring-boot-devtools.yml"));
|
||||
File file = new ClassPathResource("spring-devtools.yaml", getClass()).getFile();
|
||||
byte[] content = Files.readAllBytes(file.toPath());
|
||||
@@ -86,7 +86,7 @@ class DevToolsHomePropertiesPostProcessorTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void loadsPropertiesFromConfigFolderUsingYaml() throws Exception {
|
||||
void loadsPropertiesFromConfigDirectoryUsingYaml() throws Exception {
|
||||
OutputStream out = new FileOutputStream(new File(this.configDir, "spring-boot-devtools.yaml"));
|
||||
File file = new ClassPathResource("spring-devtools.yaml", getClass()).getFile();
|
||||
byte[] content = Files.readAllBytes(file.toPath());
|
||||
@@ -97,7 +97,7 @@ class DevToolsHomePropertiesPostProcessorTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void loadFromConfigFolderWithPropertiesTakingPrecedence() throws Exception {
|
||||
void loadFromConfigDirectoryWithPropertiesTakingPrecedence() throws Exception {
|
||||
OutputStream out = new FileOutputStream(new File(this.configDir, "spring-boot-devtools.yaml"));
|
||||
File file = new ClassPathResource("spring-devtools.yaml", getClass()).getFile();
|
||||
byte[] content = Files.readAllBytes(file.toPath());
|
||||
@@ -114,7 +114,7 @@ class DevToolsHomePropertiesPostProcessorTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void loadFromConfigFolderTakesPrecedenceOverHomeFolder() throws Exception {
|
||||
void loadFromConfigDirectoryTakesPrecedenceOverHomeDirectory() throws Exception {
|
||||
Properties properties = new Properties();
|
||||
properties.put("abc", "def");
|
||||
properties.put("bar", "baz");
|
||||
@@ -130,7 +130,7 @@ class DevToolsHomePropertiesPostProcessorTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void loadFromConfigFolderWithYamlTakesPrecedenceOverHomeFolder() throws Exception {
|
||||
void loadFromConfigDirectoryWithYamlTakesPrecedenceOverHomeDirectory() throws Exception {
|
||||
Properties properties = new Properties();
|
||||
properties.put("abc.xyz", "jkl");
|
||||
properties.put("bar", "baz");
|
||||
@@ -173,7 +173,7 @@ class DevToolsHomePropertiesPostProcessorTests {
|
||||
private class MockDevToolHomePropertiesPostProcessor extends DevToolsHomePropertiesPostProcessor {
|
||||
|
||||
@Override
|
||||
protected File getHomeFolder() {
|
||||
protected File getHomeDirectory() {
|
||||
return DevToolsHomePropertiesPostProcessorTests.this.home;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -37,45 +37,44 @@ class ChangedFileTests {
|
||||
File tempDir;
|
||||
|
||||
@Test
|
||||
void sourceFolderMustNotBeNull() throws Exception {
|
||||
void sourceDirectoryMustNotBeNull() throws Exception {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> new ChangedFile(null, new File(this.tempDir, "file"), Type.ADD))
|
||||
.withMessageContaining("SourceFolder must not be null");
|
||||
.withMessageContaining("SourceDirectory must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void fileMustNotBeNull() throws Exception {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> new ChangedFile(new File(this.tempDir, "folder"), null, Type.ADD))
|
||||
.isThrownBy(() -> new ChangedFile(new File(this.tempDir, "directory"), null, Type.ADD))
|
||||
.withMessageContaining("File must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void typeMustNotBeNull() throws Exception {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(
|
||||
() -> new ChangedFile(new File(this.tempDir, "file"), new File(this.tempDir, "folder"), null))
|
||||
assertThatIllegalArgumentException().isThrownBy(
|
||||
() -> new ChangedFile(new File(this.tempDir, "file"), new File(this.tempDir, "directory"), null))
|
||||
.withMessageContaining("Type must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getFile() throws Exception {
|
||||
File file = new File(this.tempDir, "file");
|
||||
ChangedFile changedFile = new ChangedFile(new File(this.tempDir, "folder"), file, Type.ADD);
|
||||
ChangedFile changedFile = new ChangedFile(new File(this.tempDir, "directory"), file, Type.ADD);
|
||||
assertThat(changedFile.getFile()).isEqualTo(file);
|
||||
}
|
||||
|
||||
@Test
|
||||
void getType() throws Exception {
|
||||
ChangedFile changedFile = new ChangedFile(new File(this.tempDir, "folder"), new File(this.tempDir, "file"),
|
||||
ChangedFile changedFile = new ChangedFile(new File(this.tempDir, "directory"), new File(this.tempDir, "file"),
|
||||
Type.DELETE);
|
||||
assertThat(changedFile.getType()).isEqualTo(Type.DELETE);
|
||||
}
|
||||
|
||||
@Test
|
||||
void getRelativeName() throws Exception {
|
||||
File subFolder = new File(this.tempDir, "A");
|
||||
File file = new File(subFolder, "B.txt");
|
||||
File subDirectory = new File(this.tempDir, "A");
|
||||
File file = new File(subDirectory, "B.txt");
|
||||
ChangedFile changedFile = new ChangedFile(this.tempDir, file, Type.ADD);
|
||||
assertThat(changedFile.getRelativeName()).isEqualTo("A/B.txt");
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -31,72 +31,72 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Tests for {@link FolderSnapshot}.
|
||||
* Tests for {@link DirectorySnapshot}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class FolderSnapshotTests {
|
||||
class DirectorySnapshotTests {
|
||||
|
||||
@TempDir
|
||||
File tempDir;
|
||||
|
||||
private File folder;
|
||||
private File directory;
|
||||
|
||||
private FolderSnapshot initialSnapshot;
|
||||
private DirectorySnapshot initialSnapshot;
|
||||
|
||||
@BeforeEach
|
||||
void setup() throws Exception {
|
||||
this.folder = createTestFolderStructure();
|
||||
this.initialSnapshot = new FolderSnapshot(this.folder);
|
||||
this.directory = createTestDirectoryStructure();
|
||||
this.initialSnapshot = new DirectorySnapshot(this.directory);
|
||||
}
|
||||
|
||||
@Test
|
||||
void folderMustNotBeNull() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new FolderSnapshot(null))
|
||||
.withMessageContaining("Folder must not be null");
|
||||
void directoryMustNotBeNull() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new DirectorySnapshot(null))
|
||||
.withMessageContaining("Directory must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void folderMustNotBeFile() throws Exception {
|
||||
void directoryMustNotBeFile() throws Exception {
|
||||
File file = new File(this.tempDir, "file");
|
||||
file.createNewFile();
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new FolderSnapshot(file))
|
||||
.withMessageContaining("Folder '" + file + "' must not be a file");
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new DirectorySnapshot(file))
|
||||
.withMessageContaining("Directory '" + file + "' must not be a file");
|
||||
}
|
||||
|
||||
@Test
|
||||
void folderDoesNotHaveToExist() throws Exception {
|
||||
void directoryDoesNotHaveToExist() throws Exception {
|
||||
File file = new File(this.tempDir, "does/not/exist");
|
||||
FolderSnapshot snapshot = new FolderSnapshot(file);
|
||||
assertThat(snapshot).isEqualTo(new FolderSnapshot(file));
|
||||
DirectorySnapshot snapshot = new DirectorySnapshot(file);
|
||||
assertThat(snapshot).isEqualTo(new DirectorySnapshot(file));
|
||||
}
|
||||
|
||||
@Test
|
||||
void equalsWhenNothingHasChanged() {
|
||||
FolderSnapshot updatedSnapshot = new FolderSnapshot(this.folder);
|
||||
DirectorySnapshot updatedSnapshot = new DirectorySnapshot(this.directory);
|
||||
assertThat(this.initialSnapshot).isEqualTo(updatedSnapshot);
|
||||
assertThat(this.initialSnapshot.hashCode()).isEqualTo(updatedSnapshot.hashCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
void notEqualsWhenAFileIsAdded() throws Exception {
|
||||
new File(new File(this.folder, "folder1"), "newfile").createNewFile();
|
||||
FolderSnapshot updatedSnapshot = new FolderSnapshot(this.folder);
|
||||
new File(new File(this.directory, "directory1"), "newfile").createNewFile();
|
||||
DirectorySnapshot updatedSnapshot = new DirectorySnapshot(this.directory);
|
||||
assertThat(this.initialSnapshot).isNotEqualTo(updatedSnapshot);
|
||||
}
|
||||
|
||||
@Test
|
||||
void notEqualsWhenAFileIsDeleted() {
|
||||
new File(new File(this.folder, "folder1"), "file1").delete();
|
||||
FolderSnapshot updatedSnapshot = new FolderSnapshot(this.folder);
|
||||
new File(new File(this.directory, "directory1"), "file1").delete();
|
||||
DirectorySnapshot updatedSnapshot = new DirectorySnapshot(this.directory);
|
||||
assertThat(this.initialSnapshot).isNotEqualTo(updatedSnapshot);
|
||||
}
|
||||
|
||||
@Test
|
||||
void notEqualsWhenAFileIsModified() throws Exception {
|
||||
File file1 = new File(new File(this.folder, "folder1"), "file1");
|
||||
File file1 = new File(new File(this.directory, "directory1"), "file1");
|
||||
FileCopyUtils.copy("updatedcontent".getBytes(), file1);
|
||||
FolderSnapshot updatedSnapshot = new FolderSnapshot(this.folder);
|
||||
DirectorySnapshot updatedSnapshot = new DirectorySnapshot(this.directory);
|
||||
assertThat(this.initialSnapshot).isNotEqualTo(updatedSnapshot);
|
||||
}
|
||||
|
||||
@@ -107,30 +107,30 @@ class FolderSnapshotTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void getChangedFilesSnapshotMustBeTheSameSourceFolder() throws Exception {
|
||||
void getChangedFilesSnapshotMustBeTheSameSourceDirectory() throws Exception {
|
||||
assertThatIllegalArgumentException().isThrownBy(
|
||||
() -> this.initialSnapshot.getChangedFiles(new FolderSnapshot(createTestFolderStructure()), null))
|
||||
.withMessageContaining("Snapshot source folder must be '" + this.folder + "'");
|
||||
() -> this.initialSnapshot.getChangedFiles(new DirectorySnapshot(createTestDirectoryStructure()), null))
|
||||
.withMessageContaining("Snapshot source directory must be '" + this.directory + "'");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getChangedFilesWhenNothingHasChanged() {
|
||||
FolderSnapshot updatedSnapshot = new FolderSnapshot(this.folder);
|
||||
DirectorySnapshot updatedSnapshot = new DirectorySnapshot(this.directory);
|
||||
this.initialSnapshot.getChangedFiles(updatedSnapshot, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
void getChangedFilesWhenAFileIsAddedAndDeletedAndChanged() throws Exception {
|
||||
File folder1 = new File(this.folder, "folder1");
|
||||
File file1 = new File(folder1, "file1");
|
||||
File file2 = new File(folder1, "file2");
|
||||
File newFile = new File(folder1, "newfile");
|
||||
File directory1 = new File(this.directory, "directory1");
|
||||
File file1 = new File(directory1, "file1");
|
||||
File file2 = new File(directory1, "file2");
|
||||
File newFile = new File(directory1, "newfile");
|
||||
FileCopyUtils.copy("updatedcontent".getBytes(), file1);
|
||||
file2.delete();
|
||||
newFile.createNewFile();
|
||||
FolderSnapshot updatedSnapshot = new FolderSnapshot(this.folder);
|
||||
DirectorySnapshot updatedSnapshot = new DirectorySnapshot(this.directory);
|
||||
ChangedFiles changedFiles = this.initialSnapshot.getChangedFiles(updatedSnapshot, null);
|
||||
assertThat(changedFiles.getSourceFolder()).isEqualTo(this.folder);
|
||||
assertThat(changedFiles.getSourceDirectory()).isEqualTo(this.directory);
|
||||
assertThat(getChangedFile(changedFiles, file1).getType()).isEqualTo(Type.MODIFY);
|
||||
assertThat(getChangedFile(changedFiles, file2).getType()).isEqualTo(Type.DELETE);
|
||||
assertThat(getChangedFile(changedFiles, newFile).getType()).isEqualTo(Type.ADD);
|
||||
@@ -145,12 +145,12 @@ class FolderSnapshotTests {
|
||||
return null;
|
||||
}
|
||||
|
||||
private File createTestFolderStructure() throws IOException {
|
||||
private File createTestDirectoryStructure() throws IOException {
|
||||
File root = new File(this.tempDir, UUID.randomUUID().toString());
|
||||
File folder1 = new File(root, "folder1");
|
||||
folder1.mkdirs();
|
||||
FileCopyUtils.copy("abc".getBytes(), new File(folder1, "file1"));
|
||||
FileCopyUtils.copy("abc".getBytes(), new File(folder1, "file2"));
|
||||
File directory1 = new File(root, "directory1");
|
||||
directory1.mkdirs();
|
||||
FileCopyUtils.copy("abc".getBytes(), new File(directory1, "file1"));
|
||||
FileCopyUtils.copy("abc".getBytes(), new File(directory1, "file2"));
|
||||
return root;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -51,11 +51,11 @@ class FileSnapshotTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void fileMustNotBeAFolder() throws Exception {
|
||||
void fileMustNotBeADirectory() throws Exception {
|
||||
File file = new File(this.tempDir, "file");
|
||||
file.mkdir();
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new FileSnapshot(file))
|
||||
.withMessageContaining("File must not be a folder");
|
||||
.withMessageContaining("File must not be a directory");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -94,70 +94,70 @@ class FileSystemWatcherTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void sourceFolderMustNotBeNull() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> this.watcher.addSourceFolder(null))
|
||||
.withMessageContaining("Folder must not be null");
|
||||
void sourceDirectoryMustNotBeNull() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> this.watcher.addSourceDirectory(null))
|
||||
.withMessageContaining("Directory must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void sourceFolderMustNotBeAFile() throws IOException {
|
||||
void sourceDirectoryMustNotBeAFile() throws IOException {
|
||||
File file = new File(this.tempDir, "file");
|
||||
assertThat(file.createNewFile()).isTrue();
|
||||
assertThat(file.isFile()).isTrue();
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> this.watcher.addSourceFolder(file))
|
||||
.withMessageContaining("Folder '" + file + "' must not be a file");
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> this.watcher.addSourceDirectory(file))
|
||||
.withMessageContaining("Directory '" + file + "' must not be a file");
|
||||
}
|
||||
|
||||
@Test
|
||||
void cannotAddSourceFolderToStartedListener() throws Exception {
|
||||
void cannotAddSourceDirectoryToStartedListener() throws Exception {
|
||||
this.watcher.start();
|
||||
assertThatIllegalStateException().isThrownBy(() -> this.watcher.addSourceFolder(this.tempDir))
|
||||
assertThatIllegalStateException().isThrownBy(() -> this.watcher.addSourceDirectory(this.tempDir))
|
||||
.withMessageContaining("FileSystemWatcher already started");
|
||||
}
|
||||
|
||||
@Test
|
||||
void addFile() throws Exception {
|
||||
File folder = startWithNewFolder();
|
||||
File file = touch(new File(folder, "test.txt"));
|
||||
File directory = startWithNewDirectory();
|
||||
File file = touch(new File(directory, "test.txt"));
|
||||
this.watcher.stopAfter(1);
|
||||
ChangedFiles changedFiles = getSingleChangedFiles();
|
||||
ChangedFile expected = new ChangedFile(folder, file, Type.ADD);
|
||||
ChangedFile expected = new ChangedFile(directory, file, Type.ADD);
|
||||
assertThat(changedFiles.getFiles()).contains(expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
void addNestedFile() throws Exception {
|
||||
File folder = startWithNewFolder();
|
||||
File file = touch(new File(new File(folder, "sub"), "text.txt"));
|
||||
File directory = startWithNewDirectory();
|
||||
File file = touch(new File(new File(directory, "sub"), "text.txt"));
|
||||
this.watcher.stopAfter(1);
|
||||
ChangedFiles changedFiles = getSingleChangedFiles();
|
||||
ChangedFile expected = new ChangedFile(folder, file, Type.ADD);
|
||||
ChangedFile expected = new ChangedFile(directory, file, Type.ADD);
|
||||
assertThat(changedFiles.getFiles()).contains(expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
void createSourceFolderAndAddFile() throws IOException {
|
||||
File folder = new File(this.tempDir, "does/not/exist");
|
||||
assertThat(folder.exists()).isFalse();
|
||||
this.watcher.addSourceFolder(folder);
|
||||
void createSourceDirectoryAndAddFile() throws IOException {
|
||||
File directory = new File(this.tempDir, "does/not/exist");
|
||||
assertThat(directory.exists()).isFalse();
|
||||
this.watcher.addSourceDirectory(directory);
|
||||
this.watcher.start();
|
||||
folder.mkdirs();
|
||||
File file = touch(new File(folder, "text.txt"));
|
||||
directory.mkdirs();
|
||||
File file = touch(new File(directory, "text.txt"));
|
||||
this.watcher.stopAfter(1);
|
||||
ChangedFiles changedFiles = getSingleChangedFiles();
|
||||
ChangedFile expected = new ChangedFile(folder, file, Type.ADD);
|
||||
ChangedFile expected = new ChangedFile(directory, file, Type.ADD);
|
||||
assertThat(changedFiles.getFiles()).contains(expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
void waitsForPollingInterval() throws Exception {
|
||||
setupWatcher(10, 1);
|
||||
File folder = startWithNewFolder();
|
||||
touch(new File(folder, "test1.txt"));
|
||||
File directory = startWithNewDirectory();
|
||||
touch(new File(directory, "test1.txt"));
|
||||
while (this.changes.size() != 1) {
|
||||
Thread.sleep(10);
|
||||
}
|
||||
touch(new File(folder, "test2.txt"));
|
||||
touch(new File(directory, "test2.txt"));
|
||||
this.watcher.stopAfter(1);
|
||||
assertThat(this.changes.size()).isEqualTo(2);
|
||||
}
|
||||
@@ -165,9 +165,9 @@ class FileSystemWatcherTests {
|
||||
@Test
|
||||
void waitsForQuietPeriod() throws Exception {
|
||||
setupWatcher(300, 200);
|
||||
File folder = startWithNewFolder();
|
||||
File directory = startWithNewDirectory();
|
||||
for (int i = 0; i < 10; i++) {
|
||||
touch(new File(folder, i + "test.txt"));
|
||||
touch(new File(directory, i + "test.txt"));
|
||||
Thread.sleep(100);
|
||||
}
|
||||
this.watcher.stopAfter(1);
|
||||
@@ -177,39 +177,39 @@ class FileSystemWatcherTests {
|
||||
|
||||
@Test
|
||||
void withExistingFiles() throws Exception {
|
||||
File folder = new File(this.tempDir, UUID.randomUUID().toString());
|
||||
folder.mkdir();
|
||||
touch(new File(folder, "test.txt"));
|
||||
this.watcher.addSourceFolder(folder);
|
||||
File directory = new File(this.tempDir, UUID.randomUUID().toString());
|
||||
directory.mkdir();
|
||||
touch(new File(directory, "test.txt"));
|
||||
this.watcher.addSourceDirectory(directory);
|
||||
this.watcher.start();
|
||||
File file = touch(new File(folder, "test2.txt"));
|
||||
File file = touch(new File(directory, "test2.txt"));
|
||||
this.watcher.stopAfter(1);
|
||||
ChangedFiles changedFiles = getSingleChangedFiles();
|
||||
ChangedFile expected = new ChangedFile(folder, file, Type.ADD);
|
||||
ChangedFile expected = new ChangedFile(directory, file, Type.ADD);
|
||||
assertThat(changedFiles.getFiles()).contains(expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
void multipleSources() throws Exception {
|
||||
File folder1 = new File(this.tempDir, UUID.randomUUID().toString());
|
||||
folder1.mkdir();
|
||||
File folder2 = new File(this.tempDir, UUID.randomUUID().toString());
|
||||
folder2.mkdir();
|
||||
this.watcher.addSourceFolder(folder1);
|
||||
this.watcher.addSourceFolder(folder2);
|
||||
File directory1 = new File(this.tempDir, UUID.randomUUID().toString());
|
||||
directory1.mkdir();
|
||||
File directory2 = new File(this.tempDir, UUID.randomUUID().toString());
|
||||
directory2.mkdir();
|
||||
this.watcher.addSourceDirectory(directory1);
|
||||
this.watcher.addSourceDirectory(directory2);
|
||||
this.watcher.start();
|
||||
File file1 = touch(new File(folder1, "test.txt"));
|
||||
File file2 = touch(new File(folder2, "test.txt"));
|
||||
File file1 = touch(new File(directory1, "test.txt"));
|
||||
File file2 = touch(new File(directory2, "test.txt"));
|
||||
this.watcher.stopAfter(1);
|
||||
Set<ChangedFiles> change = getSingleOnChange();
|
||||
assertThat(change.size()).isEqualTo(2);
|
||||
for (ChangedFiles changedFiles : change) {
|
||||
if (changedFiles.getSourceFolder().equals(folder1)) {
|
||||
ChangedFile file = new ChangedFile(folder1, file1, Type.ADD);
|
||||
if (changedFiles.getSourceDirectory().equals(directory1)) {
|
||||
ChangedFile file = new ChangedFile(directory1, file1, Type.ADD);
|
||||
assertThat(changedFiles.getFiles()).containsOnly(file);
|
||||
}
|
||||
else {
|
||||
ChangedFile file = new ChangedFile(folder2, file2, Type.ADD);
|
||||
ChangedFile file = new ChangedFile(directory2, file2, Type.ADD);
|
||||
assertThat(changedFiles.getFiles()).containsOnly(file);
|
||||
}
|
||||
}
|
||||
@@ -217,48 +217,48 @@ class FileSystemWatcherTests {
|
||||
|
||||
@Test
|
||||
void multipleListeners() throws Exception {
|
||||
File folder = new File(this.tempDir, UUID.randomUUID().toString());
|
||||
folder.mkdir();
|
||||
File directory = new File(this.tempDir, UUID.randomUUID().toString());
|
||||
directory.mkdir();
|
||||
final Set<ChangedFiles> listener2Changes = new LinkedHashSet<>();
|
||||
this.watcher.addSourceFolder(folder);
|
||||
this.watcher.addSourceDirectory(directory);
|
||||
this.watcher.addListener(listener2Changes::addAll);
|
||||
this.watcher.start();
|
||||
File file = touch(new File(folder, "test.txt"));
|
||||
File file = touch(new File(directory, "test.txt"));
|
||||
this.watcher.stopAfter(1);
|
||||
ChangedFiles changedFiles = getSingleChangedFiles();
|
||||
ChangedFile expected = new ChangedFile(folder, file, Type.ADD);
|
||||
ChangedFile expected = new ChangedFile(directory, file, Type.ADD);
|
||||
assertThat(changedFiles.getFiles()).contains(expected);
|
||||
assertThat(listener2Changes).isEqualTo(this.changes.get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
void modifyDeleteAndAdd() throws Exception {
|
||||
File folder = new File(this.tempDir, UUID.randomUUID().toString());
|
||||
folder.mkdir();
|
||||
File modify = touch(new File(folder, "modify.txt"));
|
||||
File delete = touch(new File(folder, "delete.txt"));
|
||||
this.watcher.addSourceFolder(folder);
|
||||
File directory = new File(this.tempDir, UUID.randomUUID().toString());
|
||||
directory.mkdir();
|
||||
File modify = touch(new File(directory, "modify.txt"));
|
||||
File delete = touch(new File(directory, "delete.txt"));
|
||||
this.watcher.addSourceDirectory(directory);
|
||||
this.watcher.start();
|
||||
FileCopyUtils.copy("abc".getBytes(), modify);
|
||||
delete.delete();
|
||||
File add = touch(new File(folder, "add.txt"));
|
||||
File add = touch(new File(directory, "add.txt"));
|
||||
this.watcher.stopAfter(1);
|
||||
ChangedFiles changedFiles = getSingleChangedFiles();
|
||||
Set<ChangedFile> actual = changedFiles.getFiles();
|
||||
Set<ChangedFile> expected = new HashSet<>();
|
||||
expected.add(new ChangedFile(folder, modify, Type.MODIFY));
|
||||
expected.add(new ChangedFile(folder, delete, Type.DELETE));
|
||||
expected.add(new ChangedFile(folder, add, Type.ADD));
|
||||
expected.add(new ChangedFile(directory, modify, Type.MODIFY));
|
||||
expected.add(new ChangedFile(directory, delete, Type.DELETE));
|
||||
expected.add(new ChangedFile(directory, add, Type.ADD));
|
||||
assertThat(actual).isEqualTo(expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
void withTriggerFilter() throws Exception {
|
||||
File folder = new File(this.tempDir, UUID.randomUUID().toString());
|
||||
folder.mkdir();
|
||||
File file = touch(new File(folder, "file.txt"));
|
||||
File trigger = touch(new File(folder, "trigger.txt"));
|
||||
this.watcher.addSourceFolder(folder);
|
||||
File directory = new File(this.tempDir, UUID.randomUUID().toString());
|
||||
directory.mkdir();
|
||||
File file = touch(new File(directory, "file.txt"));
|
||||
File trigger = touch(new File(directory, "trigger.txt"));
|
||||
this.watcher.addSourceDirectory(directory);
|
||||
this.watcher.setTriggerFilter((candidate) -> candidate.getName().equals("trigger.txt"));
|
||||
this.watcher.start();
|
||||
FileCopyUtils.copy("abc".getBytes(), file);
|
||||
@@ -269,7 +269,7 @@ class FileSystemWatcherTests {
|
||||
ChangedFiles changedFiles = getSingleChangedFiles();
|
||||
Set<ChangedFile> actual = changedFiles.getFiles();
|
||||
Set<ChangedFile> expected = new HashSet<>();
|
||||
expected.add(new ChangedFile(folder, file, Type.MODIFY));
|
||||
expected.add(new ChangedFile(directory, file, Type.MODIFY));
|
||||
assertThat(actual).isEqualTo(expected);
|
||||
}
|
||||
|
||||
@@ -278,12 +278,12 @@ class FileSystemWatcherTests {
|
||||
this.watcher.addListener((changeSet) -> FileSystemWatcherTests.this.changes.add(changeSet));
|
||||
}
|
||||
|
||||
private File startWithNewFolder() throws IOException {
|
||||
File folder = new File(this.tempDir, UUID.randomUUID().toString());
|
||||
folder.mkdir();
|
||||
this.watcher.addSourceFolder(folder);
|
||||
private File startWithNewDirectory() throws IOException {
|
||||
File directory = new File(this.tempDir, UUID.randomUUID().toString());
|
||||
directory.mkdir();
|
||||
this.watcher.addSourceDirectory(directory);
|
||||
this.watcher.start();
|
||||
return folder;
|
||||
return directory;
|
||||
}
|
||||
|
||||
private ChangedFiles getSingleChangedFiles() {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -37,7 +37,7 @@ import org.springframework.boot.devtools.filewatch.ChangedFiles;
|
||||
import org.springframework.boot.devtools.restart.classloader.ClassLoaderFile;
|
||||
import org.springframework.boot.devtools.restart.classloader.ClassLoaderFile.Kind;
|
||||
import org.springframework.boot.devtools.restart.classloader.ClassLoaderFiles;
|
||||
import org.springframework.boot.devtools.restart.classloader.ClassLoaderFiles.SourceFolder;
|
||||
import org.springframework.boot.devtools.restart.classloader.ClassLoaderFiles.SourceDirectory;
|
||||
import org.springframework.boot.devtools.test.MockClientHttpRequestFactory;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.mock.http.client.MockClientHttpRequest;
|
||||
@@ -91,33 +91,33 @@ class ClassPathChangeUploaderTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void sendsClassLoaderFiles(@TempDir File sourceFolder) throws Exception {
|
||||
ClassPathChangedEvent event = createClassPathChangedEvent(sourceFolder);
|
||||
void sendsClassLoaderFiles(@TempDir File sourceDirectory) throws Exception {
|
||||
ClassPathChangedEvent event = createClassPathChangedEvent(sourceDirectory);
|
||||
this.requestFactory.willRespond(HttpStatus.OK);
|
||||
this.uploader.onApplicationEvent(event);
|
||||
assertThat(this.requestFactory.getExecutedRequests()).hasSize(1);
|
||||
MockClientHttpRequest request = this.requestFactory.getExecutedRequests().get(0);
|
||||
verifyUploadRequest(sourceFolder, request);
|
||||
verifyUploadRequest(sourceDirectory, request);
|
||||
}
|
||||
|
||||
@Test
|
||||
void retriesOnSocketException(@TempDir File sourceFolder) throws Exception {
|
||||
ClassPathChangedEvent event = createClassPathChangedEvent(sourceFolder);
|
||||
void retriesOnSocketException(@TempDir File sourceDirectory) throws Exception {
|
||||
ClassPathChangedEvent event = createClassPathChangedEvent(sourceDirectory);
|
||||
this.requestFactory.willRespond(new SocketException());
|
||||
this.requestFactory.willRespond(HttpStatus.OK);
|
||||
this.uploader.onApplicationEvent(event);
|
||||
assertThat(this.requestFactory.getExecutedRequests()).hasSize(2);
|
||||
verifyUploadRequest(sourceFolder, this.requestFactory.getExecutedRequests().get(1));
|
||||
verifyUploadRequest(sourceDirectory, this.requestFactory.getExecutedRequests().get(1));
|
||||
}
|
||||
|
||||
private void verifyUploadRequest(File sourceFolder, MockClientHttpRequest request)
|
||||
private void verifyUploadRequest(File sourceDirectory, MockClientHttpRequest request)
|
||||
throws IOException, ClassNotFoundException {
|
||||
ClassLoaderFiles classLoaderFiles = deserialize(request.getBodyAsBytes());
|
||||
Collection<SourceFolder> sourceFolders = classLoaderFiles.getSourceFolders();
|
||||
assertThat(sourceFolders.size()).isEqualTo(1);
|
||||
SourceFolder classSourceFolder = sourceFolders.iterator().next();
|
||||
assertThat(classSourceFolder.getName()).isEqualTo(sourceFolder.getAbsolutePath());
|
||||
Iterator<ClassLoaderFile> classFiles = classSourceFolder.getFiles().iterator();
|
||||
Collection<SourceDirectory> sourceDirectories = classLoaderFiles.getSourceDirectories();
|
||||
assertThat(sourceDirectories.size()).isEqualTo(1);
|
||||
SourceDirectory classSourceDirectory = sourceDirectories.iterator().next();
|
||||
assertThat(classSourceDirectory.getName()).isEqualTo(sourceDirectory.getAbsolutePath());
|
||||
Iterator<ClassLoaderFile> classFiles = classSourceDirectory.getFiles().iterator();
|
||||
assertClassFile(classFiles.next(), "File1", ClassLoaderFile.Kind.ADDED);
|
||||
assertClassFile(classFiles.next(), "File2", ClassLoaderFile.Kind.MODIFIED);
|
||||
assertClassFile(classFiles.next(), null, ClassLoaderFile.Kind.DELETED);
|
||||
@@ -129,21 +129,21 @@ class ClassPathChangeUploaderTests {
|
||||
assertThat(file.getKind()).isEqualTo(kind);
|
||||
}
|
||||
|
||||
private ClassPathChangedEvent createClassPathChangedEvent(File sourceFolder) throws IOException {
|
||||
private ClassPathChangedEvent createClassPathChangedEvent(File sourceDirectory) throws IOException {
|
||||
Set<ChangedFile> files = new LinkedHashSet<>();
|
||||
File file1 = createFile(sourceFolder, "File1");
|
||||
File file2 = createFile(sourceFolder, "File2");
|
||||
File file3 = createFile(sourceFolder, "File3");
|
||||
files.add(new ChangedFile(sourceFolder, file1, Type.ADD));
|
||||
files.add(new ChangedFile(sourceFolder, file2, Type.MODIFY));
|
||||
files.add(new ChangedFile(sourceFolder, file3, Type.DELETE));
|
||||
File file1 = createFile(sourceDirectory, "File1");
|
||||
File file2 = createFile(sourceDirectory, "File2");
|
||||
File file3 = createFile(sourceDirectory, "File3");
|
||||
files.add(new ChangedFile(sourceDirectory, file1, Type.ADD));
|
||||
files.add(new ChangedFile(sourceDirectory, file2, Type.MODIFY));
|
||||
files.add(new ChangedFile(sourceDirectory, file3, Type.DELETE));
|
||||
Set<ChangedFiles> changeSet = new LinkedHashSet<>();
|
||||
changeSet.add(new ChangedFiles(sourceFolder, files));
|
||||
changeSet.add(new ChangedFiles(sourceDirectory, files));
|
||||
return new ClassPathChangedEvent(this, changeSet, false);
|
||||
}
|
||||
|
||||
private File createFile(File sourceFolder, String name) throws IOException {
|
||||
File file = new File(sourceFolder, name);
|
||||
private File createFile(File sourceDirectory, String name) throws IOException {
|
||||
File file = new File(sourceDirectory, name);
|
||||
FileCopyUtils.copy(name.getBytes(), file);
|
||||
return file;
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ class ChangeableUrlsTests {
|
||||
File tempDir;
|
||||
|
||||
@Test
|
||||
void folderUrl() throws Exception {
|
||||
void directoryUrl() throws Exception {
|
||||
URL url = makeUrl("myproject");
|
||||
assertThat(ChangeableUrls.fromUrls(url).size()).isEqualTo(1);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -83,25 +83,25 @@ class ClassLoaderFilesResourcePatternResolverTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void getResourceWhenDeletedShouldReturnDeletedResource(@TempDir File folder) throws Exception {
|
||||
File file = createFile(folder, "name.class");
|
||||
this.files.addFile(folder.getName(), "name.class", new ClassLoaderFile(Kind.DELETED, null));
|
||||
void getResourceWhenDeletedShouldReturnDeletedResource(@TempDir File directory) throws Exception {
|
||||
File file = createFile(directory, "name.class");
|
||||
this.files.addFile(directory.getName(), "name.class", new ClassLoaderFile(Kind.DELETED, null));
|
||||
Resource resource = this.resolver.getResource("file:" + file.getAbsolutePath());
|
||||
assertThat(resource).isNotNull().isInstanceOf(DeletedClassLoaderFileResource.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void getResourcesShouldReturnResources(@TempDir File folder) throws Exception {
|
||||
createFile(folder, "name.class");
|
||||
Resource[] resources = this.resolver.getResources("file:" + folder.getAbsolutePath() + "/**");
|
||||
void getResourcesShouldReturnResources(@TempDir File directory) throws Exception {
|
||||
createFile(directory, "name.class");
|
||||
Resource[] resources = this.resolver.getResources("file:" + directory.getAbsolutePath() + "/**");
|
||||
assertThat(resources).isNotEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void getResourcesWhenDeletedShouldFilterDeleted(@TempDir File folder) throws Exception {
|
||||
createFile(folder, "name.class");
|
||||
this.files.addFile(folder.getName(), "name.class", new ClassLoaderFile(Kind.DELETED, null));
|
||||
Resource[] resources = this.resolver.getResources("file:" + folder.getAbsolutePath() + "/**");
|
||||
void getResourcesWhenDeletedShouldFilterDeleted(@TempDir File directory) throws Exception {
|
||||
createFile(directory, "name.class");
|
||||
this.files.addFile(directory.getName(), "name.class", new ClassLoaderFile(Kind.DELETED, null));
|
||||
Resource[] resources = this.resolver.getResources("file:" + directory.getAbsolutePath() + "/**");
|
||||
assertThat(resources).isEmpty();
|
||||
}
|
||||
|
||||
@@ -179,8 +179,8 @@ class ClassLoaderFilesResourcePatternResolverTests {
|
||||
return resolver;
|
||||
}
|
||||
|
||||
private File createFile(File folder, String name) throws IOException {
|
||||
File file = new File(folder, name);
|
||||
private File createFile(File directory, String name) throws IOException {
|
||||
File file = new File(directory, name);
|
||||
FileCopyUtils.copy("test".getBytes(), file);
|
||||
return file;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -25,7 +25,7 @@ import java.util.Iterator;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.devtools.restart.classloader.ClassLoaderFile.Kind;
|
||||
import org.springframework.boot.devtools.restart.classloader.ClassLoaderFiles.SourceFolder;
|
||||
import org.springframework.boot.devtools.restart.classloader.ClassLoaderFiles.SourceDirectory;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
@@ -79,18 +79,18 @@ class ClassLoaderFilesTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void addTwiceInDifferentSourceFolders() {
|
||||
void addTwiceInDifferentSourceDirectories() {
|
||||
ClassLoaderFile file1 = new ClassLoaderFile(Kind.ADDED, new byte[10]);
|
||||
ClassLoaderFile file2 = new ClassLoaderFile(Kind.MODIFIED, new byte[10]);
|
||||
this.files.addFile("a", "myfile", file1);
|
||||
this.files.addFile("b", "myfile", file2);
|
||||
assertThat(this.files.getFile("myfile")).isEqualTo(file2);
|
||||
assertThat(this.files.getOrCreateSourceFolder("a").getFiles().size()).isEqualTo(0);
|
||||
assertThat(this.files.getOrCreateSourceFolder("b").getFiles().size()).isEqualTo(1);
|
||||
assertThat(this.files.getOrCreateSourceDirectory("a").getFiles().size()).isEqualTo(0);
|
||||
assertThat(this.files.getOrCreateSourceDirectory("b").getFiles().size()).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void getSourceFolders() {
|
||||
void getSourceDirectories() {
|
||||
ClassLoaderFile file1 = new ClassLoaderFile(Kind.ADDED, new byte[10]);
|
||||
ClassLoaderFile file2 = new ClassLoaderFile(Kind.MODIFIED, new byte[10]);
|
||||
ClassLoaderFile file3 = new ClassLoaderFile(Kind.MODIFIED, new byte[10]);
|
||||
@@ -99,14 +99,14 @@ class ClassLoaderFilesTests {
|
||||
this.files.addFile("a", "myfile2", file2);
|
||||
this.files.addFile("b", "myfile3", file3);
|
||||
this.files.addFile("b", "myfile4", file4);
|
||||
Iterator<SourceFolder> sourceFolders = this.files.getSourceFolders().iterator();
|
||||
SourceFolder sourceFolder1 = sourceFolders.next();
|
||||
SourceFolder sourceFolder2 = sourceFolders.next();
|
||||
assertThat(sourceFolders.hasNext()).isFalse();
|
||||
assertThat(sourceFolder1.getName()).isEqualTo("a");
|
||||
assertThat(sourceFolder2.getName()).isEqualTo("b");
|
||||
assertThat(sourceFolder1.getFiles()).containsOnly(file1, file2);
|
||||
assertThat(sourceFolder2.getFiles()).containsOnly(file3, file4);
|
||||
Iterator<SourceDirectory> sourceDirectories = this.files.getSourceDirectories().iterator();
|
||||
SourceDirectory sourceDirectory1 = sourceDirectories.next();
|
||||
SourceDirectory sourceDirectory2 = sourceDirectories.next();
|
||||
assertThat(sourceDirectories.hasNext()).isFalse();
|
||||
assertThat(sourceDirectory1.getName()).isEqualTo("a");
|
||||
assertThat(sourceDirectory2.getName()).isEqualTo("b");
|
||||
assertThat(sourceDirectory1.getFiles()).containsOnly(file1, file2);
|
||||
assertThat(sourceDirectory2.getFiles()).containsOnly(file3, file4);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -132,13 +132,13 @@ class ClassLoaderFilesTests {
|
||||
toAdd.addFile("a", "myfile2", file2);
|
||||
toAdd.addFile("b", "myfile3", file3);
|
||||
this.files.addAll(toAdd);
|
||||
Iterator<SourceFolder> sourceFolders = this.files.getSourceFolders().iterator();
|
||||
SourceFolder sourceFolder1 = sourceFolders.next();
|
||||
SourceFolder sourceFolder2 = sourceFolders.next();
|
||||
assertThat(sourceFolders.hasNext()).isFalse();
|
||||
assertThat(sourceFolder1.getName()).isEqualTo("a");
|
||||
assertThat(sourceFolder2.getName()).isEqualTo("b");
|
||||
assertThat(sourceFolder1.getFiles()).containsOnly(file1, file2);
|
||||
Iterator<SourceDirectory> sourceDirectoryies = this.files.getSourceDirectories().iterator();
|
||||
SourceDirectory sourceDirectory1 = sourceDirectoryies.next();
|
||||
SourceDirectory sourceDirectory2 = sourceDirectoryies.next();
|
||||
assertThat(sourceDirectoryies.hasNext()).isFalse();
|
||||
assertThat(sourceDirectory1.getName()).isEqualTo("a");
|
||||
assertThat(sourceDirectory2.getName()).isEqualTo("b");
|
||||
assertThat(sourceDirectory1.getFiles()).containsOnly(file1, file2);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -27,11 +27,11 @@ import org.junit.jupiter.api.Test;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link DefaultSourceFolderUrlFilter}.
|
||||
* Tests for {@link DefaultSourceDirectoryUrlFilter}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class DefaultSourceFolderUrlFilterTests {
|
||||
class DefaultSourceDirectoryUrlFilterTests {
|
||||
|
||||
private static final String SOURCE_ROOT = "/Users/me/code/some-root/";
|
||||
|
||||
@@ -52,33 +52,33 @@ class DefaultSourceFolderUrlFilterTests {
|
||||
COMMON_POSTFIXES = Collections.unmodifiableList(postfixes);
|
||||
}
|
||||
|
||||
private DefaultSourceFolderUrlFilter filter = new DefaultSourceFolderUrlFilter();
|
||||
private DefaultSourceDirectoryUrlFilter filter = new DefaultSourceDirectoryUrlFilter();
|
||||
|
||||
@Test
|
||||
void mavenSourceFolder() throws Exception {
|
||||
void mavenSourceDirectory() throws Exception {
|
||||
doTest("my-module/target/classes/");
|
||||
}
|
||||
|
||||
@Test
|
||||
void gradleEclipseSourceFolder() throws Exception {
|
||||
void gradleEclipseSourceDirectory() throws Exception {
|
||||
doTest("my-module/bin/");
|
||||
}
|
||||
|
||||
@Test
|
||||
void unusualSourceFolder() throws Exception {
|
||||
void unusualSourceDirectory() throws Exception {
|
||||
doTest("my-module/something/quite/quite/mad/");
|
||||
}
|
||||
|
||||
@Test
|
||||
void skippedProjects() throws Exception {
|
||||
String sourceFolder = "/Users/me/code/spring-boot-samples/spring-boot-sample-devtools";
|
||||
String sourceDirectory = "/Users/me/code/spring-boot-samples/spring-boot-sample-devtools";
|
||||
URL jarUrl = new URL("jar:file:/Users/me/tmp/spring-boot-sample-devtools-1.3.0.BUILD-SNAPSHOT.jar!/");
|
||||
assertThat(this.filter.isMatch(sourceFolder, jarUrl)).isTrue();
|
||||
assertThat(this.filter.isMatch(sourceDirectory, jarUrl)).isTrue();
|
||||
URL nestedJarUrl = new URL("jar:file:/Users/me/tmp/spring-boot-sample-devtools-1.3.0.BUILD-SNAPSHOT.jar!/"
|
||||
+ "lib/spring-boot-1.3.0.BUILD-SNAPSHOT.jar!/");
|
||||
assertThat(this.filter.isMatch(sourceFolder, nestedJarUrl)).isFalse();
|
||||
assertThat(this.filter.isMatch(sourceDirectory, nestedJarUrl)).isFalse();
|
||||
URL fileUrl = new URL("file:/Users/me/tmp/spring-boot-sample-devtools-1.3.0.BUILD-SNAPSHOT.jar");
|
||||
assertThat(this.filter.isMatch(sourceFolder, fileUrl)).isTrue();
|
||||
assertThat(this.filter.isMatch(sourceDirectory, fileUrl)).isTrue();
|
||||
}
|
||||
|
||||
private void doTest(String sourcePostfix) throws MalformedURLException {
|
||||
@@ -89,11 +89,11 @@ class DefaultSourceFolderUrlFilterTests {
|
||||
}
|
||||
|
||||
private void doTest(String sourcePostfix, String moduleRoot, boolean expected) throws MalformedURLException {
|
||||
String sourceFolder = SOURCE_ROOT + sourcePostfix;
|
||||
String sourceDirectory = SOURCE_ROOT + sourcePostfix;
|
||||
for (String postfix : COMMON_POSTFIXES) {
|
||||
for (URL url : getUrls(moduleRoot + postfix)) {
|
||||
boolean match = this.filter.isMatch(sourceFolder, url);
|
||||
assertThat(match).as(url + " against " + sourceFolder).isEqualTo(expected);
|
||||
boolean match = this.filter.isMatch(sourceDirectory, url);
|
||||
assertThat(match).as(url + " against " + sourceDirectory).isEqualTo(expected);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -62,9 +62,9 @@ class HttpRestartServerTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void sourceFolderUrlFilterMustNotBeNull() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new HttpRestartServer((SourceFolderUrlFilter) null))
|
||||
.withMessageContaining("SourceFolderUrlFilter must not be null");
|
||||
void sourceDirectoryUrlFilterMustNotBeNull() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new HttpRestartServer((SourceDirectoryUrlFilter) null))
|
||||
.withMessageContaining("SourceDirectoryUrlFilter must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -43,9 +43,9 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException
|
||||
class RestartServerTests {
|
||||
|
||||
@Test
|
||||
void sourceFolderUrlFilterMustNotBeNull() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new RestartServer((SourceFolderUrlFilter) null))
|
||||
.withMessageContaining("SourceFolderUrlFilter must not be null");
|
||||
void sourceDirectoryUrlFilterMustNotBeNull() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new RestartServer((SourceDirectoryUrlFilter) null))
|
||||
.withMessageContaining("SourceDirectoryUrlFilter must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -56,7 +56,7 @@ class RestartServerTests {
|
||||
URL url4 = new URL("file:/proj/module-d.jar!/");
|
||||
URLClassLoader classLoaderA = new URLClassLoader(new URL[] { url1, url2 });
|
||||
URLClassLoader classLoaderB = new URLClassLoader(new URL[] { url3, url4 }, classLoaderA);
|
||||
SourceFolderUrlFilter filter = new DefaultSourceFolderUrlFilter();
|
||||
SourceDirectoryUrlFilter filter = new DefaultSourceDirectoryUrlFilter();
|
||||
MockRestartServer server = new MockRestartServer(filter, classLoaderB);
|
||||
ClassLoaderFiles files = new ClassLoaderFiles();
|
||||
ClassLoaderFile fileA = new ClassLoaderFile(Kind.ADDED, new byte[0]);
|
||||
@@ -70,14 +70,14 @@ class RestartServerTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void updateSetsJarLastModified(@TempDir File folder) throws Exception {
|
||||
void updateSetsJarLastModified(@TempDir File directory) throws Exception {
|
||||
long startTime = System.currentTimeMillis();
|
||||
File jarFile = new File(folder, "module-a.jar");
|
||||
File jarFile = new File(directory, "module-a.jar");
|
||||
new FileOutputStream(jarFile).close();
|
||||
jarFile.setLastModified(0);
|
||||
URL url = jarFile.toURI().toURL();
|
||||
URLClassLoader classLoader = new URLClassLoader(new URL[] { url });
|
||||
SourceFolderUrlFilter filter = new DefaultSourceFolderUrlFilter();
|
||||
SourceDirectoryUrlFilter filter = new DefaultSourceDirectoryUrlFilter();
|
||||
MockRestartServer server = new MockRestartServer(filter, classLoader);
|
||||
ClassLoaderFiles files = new ClassLoaderFiles();
|
||||
ClassLoaderFile fileA = new ClassLoaderFile(Kind.ADDED, new byte[0]);
|
||||
@@ -87,15 +87,15 @@ class RestartServerTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void updateReplacesLocalFilesWhenPossible(@TempDir File folder) throws Exception {
|
||||
void updateReplacesLocalFilesWhenPossible(@TempDir File directory) throws Exception {
|
||||
// This is critical for Cloud Foundry support where the application is
|
||||
// run exploded and resources can be found from the servlet root (outside of the
|
||||
// classloader)
|
||||
File classFile = new File(folder, "ClassA.class");
|
||||
File classFile = new File(directory, "ClassA.class");
|
||||
FileCopyUtils.copy("abc".getBytes(), classFile);
|
||||
URL url = folder.toURI().toURL();
|
||||
URL url = directory.toURI().toURL();
|
||||
URLClassLoader classLoader = new URLClassLoader(new URL[] { url });
|
||||
SourceFolderUrlFilter filter = new DefaultSourceFolderUrlFilter();
|
||||
SourceDirectoryUrlFilter filter = new DefaultSourceDirectoryUrlFilter();
|
||||
MockRestartServer server = new MockRestartServer(filter, classLoader);
|
||||
ClassLoaderFiles files = new ClassLoaderFiles();
|
||||
ClassLoaderFile fileA = new ClassLoaderFile(Kind.ADDED, "def".getBytes());
|
||||
@@ -106,8 +106,8 @@ class RestartServerTests {
|
||||
|
||||
static class MockRestartServer extends RestartServer {
|
||||
|
||||
MockRestartServer(SourceFolderUrlFilter sourceFolderUrlFilter, ClassLoader classLoader) {
|
||||
super(sourceFolderUrlFilter, classLoader);
|
||||
MockRestartServer(SourceDirectoryUrlFilter sourceDirectoryUrlFilter, ClassLoader classLoader) {
|
||||
super(sourceDirectoryUrlFilter, classLoader);
|
||||
}
|
||||
|
||||
private Set<URL> restartUrls;
|
||||
|
||||
Reference in New Issue
Block a user