Merge branch '1.4.x' into 1.5.x

pull/6961/merge
Phillip Webb 8 years ago
commit 9e18021e8c

@ -1035,8 +1035,8 @@ public class ServerProperties
private boolean renameOnRotate; private boolean renameOnRotate;
/** /**
* Set request attributes for IP address, Hostname, protocol and port used * Set request attributes for IP address, Hostname, protocol and port used for
* for the request. * the request.
*/ */
private boolean requestAttributesEnabled; private boolean requestAttributesEnabled;

@ -21,12 +21,8 @@ import java.io.InputStream;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Set;
import org.springframework.boot.devtools.restart.classloader.ClassLoaderFile; import org.springframework.boot.devtools.restart.classloader.ClassLoaderFile;
import org.springframework.boot.devtools.restart.classloader.ClassLoaderFile.Kind; import org.springframework.boot.devtools.restart.classloader.ClassLoaderFile.Kind;
@ -48,9 +44,8 @@ import org.springframework.util.AntPathMatcher;
*/ */
final class ClassLoaderFilesResourcePatternResolver implements ResourcePatternResolver { final class ClassLoaderFilesResourcePatternResolver implements ResourcePatternResolver {
private static final Set<String> LOCATION_PATTERN_PREFIXES = Collections private static final String[] LOCATION_PATTERN_PREFIXES = { CLASSPATH_ALL_URL_PREFIX,
.unmodifiableSet(new HashSet<String>( CLASSPATH_URL_PREFIX };
Arrays.asList(CLASSPATH_ALL_URL_PREFIX, CLASSPATH_URL_PREFIX)));
private final ResourcePatternResolver delegate = new PathMatchingResourcePatternResolver(); private final ResourcePatternResolver delegate = new PathMatchingResourcePatternResolver();
@ -62,26 +57,26 @@ final class ClassLoaderFilesResourcePatternResolver implements ResourcePatternRe
this.classLoaderFiles = classLoaderFiles; this.classLoaderFiles = classLoaderFiles;
} }
@Override
public ClassLoader getClassLoader() {
return this.delegate.getClassLoader();
}
@Override @Override
public Resource getResource(String location) { public Resource getResource(String location) {
Resource candidate = this.delegate.getResource(location); Resource candidate = this.delegate.getResource(location);
if (isExcludedResource(candidate)) { if (isDeleted(candidate)) {
return new DeletedClassLoaderFileResource(location); return new DeletedClassLoaderFileResource(location);
} }
return candidate; return candidate;
} }
@Override
public ClassLoader getClassLoader() {
return this.delegate.getClassLoader();
}
@Override @Override
public Resource[] getResources(String locationPattern) throws IOException { public Resource[] getResources(String locationPattern) throws IOException {
List<Resource> resources = new ArrayList<Resource>(); List<Resource> resources = new ArrayList<Resource>();
Resource[] candidates = this.delegate.getResources(locationPattern); Resource[] candidates = this.delegate.getResources(locationPattern);
for (Resource candidate : candidates) { for (Resource candidate : candidates) {
if (!isExcludedResource(candidate)) { if (!isDeleted(candidate)) {
resources.add(candidate); resources.add(candidate);
} }
} }
@ -89,38 +84,43 @@ final class ClassLoaderFilesResourcePatternResolver implements ResourcePatternRe
return resources.toArray(new Resource[resources.size()]); return resources.toArray(new Resource[resources.size()]);
} }
private String trimLocationPattern(String locationPattern) {
for (String prefix : LOCATION_PATTERN_PREFIXES) {
if (locationPattern.startsWith(prefix)) {
return locationPattern.substring(prefix.length());
}
}
return locationPattern;
}
private List<Resource> getAdditionalResources(String locationPattern) private List<Resource> getAdditionalResources(String locationPattern)
throws MalformedURLException { throws MalformedURLException {
List<Resource> additionalResources = new ArrayList<Resource>(); List<Resource> additionalResources = new ArrayList<Resource>();
String trimmedLocationPattern = trimLocationPattern(locationPattern); String trimmedLocationPattern = trimLocationPattern(locationPattern);
for (SourceFolder sourceFolder : this.classLoaderFiles.getSourceFolders()) { for (SourceFolder sourceFolder : this.classLoaderFiles.getSourceFolders()) {
for (Entry<String, ClassLoaderFile> entry : sourceFolder.getFilesEntrySet()) { for (Entry<String, ClassLoaderFile> entry : sourceFolder.getFilesEntrySet()) {
if (entry.getValue().getKind() == Kind.ADDED && this.antPathMatcher String name = entry.getKey();
.match(trimmedLocationPattern, entry.getKey())) { ClassLoaderFile file = entry.getValue();
additionalResources.add(new UrlResource(new URL("reloaded", null, -1, if (file.getKind() == Kind.ADDED
"/" + entry.getKey(), && this.antPathMatcher.match(trimmedLocationPattern, name)) {
new ClassLoaderFileURLStreamHandler(entry.getValue())))); URL url = new URL("reloaded", null, -1, "/" + name,
new ClassLoaderFileURLStreamHandler(file));
UrlResource resource = new UrlResource(url);
additionalResources.add(resource);
} }
} }
} }
return additionalResources; return additionalResources;
} }
private boolean isExcludedResource(Resource resource) { private String trimLocationPattern(String pattern) {
for (String prefix : LOCATION_PATTERN_PREFIXES) {
if (pattern.startsWith(prefix)) {
return pattern.substring(prefix.length());
}
}
return pattern;
}
private boolean isDeleted(Resource resource) {
for (SourceFolder sourceFolder : this.classLoaderFiles.getSourceFolders()) { for (SourceFolder sourceFolder : this.classLoaderFiles.getSourceFolders()) {
for (Entry<String, ClassLoaderFile> entry : sourceFolder.getFilesEntrySet()) { for (Entry<String, ClassLoaderFile> entry : sourceFolder.getFilesEntrySet()) {
try { try {
if (entry.getValue().getKind() == Kind.DELETED && resource.exists() String name = entry.getKey();
&& resource.getURI().toString().endsWith(entry.getKey())) { ClassLoaderFile file = entry.getValue();
if (file.getKind() == Kind.DELETED && resource.exists()
&& resource.getURI().toString().endsWith(name)) {
return true; return true;
} }
} }
@ -136,8 +136,6 @@ final class ClassLoaderFilesResourcePatternResolver implements ResourcePatternRe
/** /**
* A {@link Resource} that represents a {@link ClassLoaderFile} that has been * A {@link Resource} that represents a {@link ClassLoaderFile} that has been
* {@link Kind#DELETED deleted}. * {@link Kind#DELETED deleted}.
*
* @author Andy Wilkinson
*/ */
private final class DeletedClassLoaderFileResource extends AbstractResource { private final class DeletedClassLoaderFileResource extends AbstractResource {
@ -161,5 +159,7 @@ final class ClassLoaderFilesResourcePatternResolver implements ResourcePatternRe
public InputStream getInputStream() throws IOException { public InputStream getInputStream() throws IOException {
throw new IOException(this.name + " has been deleted"); throw new IOException(this.name + " has been deleted");
} }
} }
} }

@ -421,8 +421,7 @@ public class Restarter {
return; return;
} }
if (applicationContext instanceof GenericApplicationContext) { if (applicationContext instanceof GenericApplicationContext) {
((GenericApplicationContext) applicationContext).setResourceLoader( prepare((GenericApplicationContext) applicationContext);
new ClassLoaderFilesResourcePatternResolver(this.classLoaderFiles));
} }
this.rootContexts.add(applicationContext); this.rootContexts.add(applicationContext);
} }
@ -433,6 +432,11 @@ public class Restarter {
} }
} }
private void prepare(GenericApplicationContext applicationContext) {
applicationContext.setResourceLoader(
new ClassLoaderFilesResourcePatternResolver(this.classLoaderFiles));
}
private LeakSafeThread getLeakSafeThread() { private LeakSafeThread getLeakSafeThread() {
try { try {
return this.leakSafeThreads.takeFirst(); return this.leakSafeThreads.takeFirst();

@ -27,6 +27,7 @@ import java.net.URLStreamHandler;
* {@link URLStreamHandler} for the contents of a {@link ClassLoaderFile}. * {@link URLStreamHandler} for the contents of a {@link ClassLoaderFile}.
* *
* @author Phillip Webb * @author Phillip Webb
* @since 1.5.0
*/ */
public class ClassLoaderFileURLStreamHandler extends URLStreamHandler { public class ClassLoaderFileURLStreamHandler extends URLStreamHandler {

@ -146,8 +146,8 @@ public class DevToolsIntegrationTests {
} }
Thread.sleep(100); Thread.sleep(100);
} }
int port = Integer FileReader portReader = new FileReader(this.serverPortFile);
.valueOf(FileCopyUtils.copyToString(new FileReader(this.serverPortFile))); int port = Integer.valueOf(FileCopyUtils.copyToString(portReader));
this.serverPortFile.delete(); this.serverPortFile.delete();
return port; return port;
} }
@ -187,5 +187,7 @@ public class DevToolsIntegrationTests {
} }
builder.make().saveIn(this.classesDirectory); builder.make().saveIn(this.classesDirectory);
} }
} }
} }

Loading…
Cancel
Save