Replace "folder" with "directory"

Consistently use the term "directory" instead of "folder"

Closes gh-21218
This commit is contained in:
Phillip Webb
2020-04-28 18:27:41 -07:00
parent ec871d6752
commit ad1248e4ec
98 changed files with 853 additions and 835 deletions

View 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.
@@ -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 {

View 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.
@@ -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;
}

View 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.
@@ -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

View 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.
@@ -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();
}
}

View 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.
@@ -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));
}
/**

View 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.
@@ -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);

View 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.
@@ -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

View 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.
@@ -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;
}
}

View File

@@ -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;
}
}

View 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.
@@ -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();

View File

@@ -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) {

View 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.
@@ -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;

View 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.
@@ -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("/");
}

View File

@@ -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();

View 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.
@@ -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());

View 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.
@@ -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();
}

View 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.
@@ -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);
}
/**

View 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.
@@ -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);
}

View 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.
@@ -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);
}