From 573ff2c58d95e26432e36d6600d863b1fe6d3e9f Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Thu, 2 Nov 2017 16:05:57 +0100 Subject: [PATCH] ClassPathResource uses specific constructors in createRelative Issue: SPR-16146 (cherry picked from commit d00e4f1) --- .../core/io/ClassPathResource.java | 5 +- .../core/io/ClassPathResourceTests.java | 116 ++++++++++-------- 2 files changed, 67 insertions(+), 54 deletions(-) diff --git a/spring-core/src/main/java/org/springframework/core/io/ClassPathResource.java b/spring-core/src/main/java/org/springframework/core/io/ClassPathResource.java index 10a379700e..5a71b2bf1d 100644 --- a/spring-core/src/main/java/org/springframework/core/io/ClassPathResource.java +++ b/spring-core/src/main/java/org/springframework/core/io/ClassPathResource.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2017 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. @@ -197,7 +197,8 @@ public class ClassPathResource extends AbstractFileResolvingResource { @Override public Resource createRelative(String relativePath) { String pathToUse = StringUtils.applyRelativePath(this.path, relativePath); - return new ClassPathResource(pathToUse, this.classLoader, this.clazz); + return (this.clazz != null ? new ClassPathResource(pathToUse, this.clazz) : + new ClassPathResource(pathToUse, this.classLoader)); } /** diff --git a/spring-core/src/test/java/org/springframework/core/io/ClassPathResourceTests.java b/spring-core/src/test/java/org/springframework/core/io/ClassPathResourceTests.java index 67e1c49d9d..6319742edb 100644 --- a/spring-core/src/test/java/org/springframework/core/io/ClassPathResourceTests.java +++ b/spring-core/src/test/java/org/springframework/core/io/ClassPathResourceTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2017 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. @@ -47,6 +47,69 @@ public class ClassPathResourceTests { private static final Pattern DESCRIPTION_PATTERN = Pattern.compile("^class path resource \\[(.+?)\\]$"); + @Test + public void stringConstructorRaisesExceptionWithFullyQualifiedPath() { + assertExceptionContainsFullyQualifiedPath(new ClassPathResource(FQ_RESOURCE_PATH)); + } + + @Test + public void classLiteralConstructorRaisesExceptionWithFullyQualifiedPath() { + assertExceptionContainsFullyQualifiedPath(new ClassPathResource(NONEXISTENT_RESOURCE_NAME, getClass())); + } + + @Test + public void classLoaderConstructorRaisesExceptionWithFullyQualifiedPath() { + assertExceptionContainsFullyQualifiedPath(new ClassPathResource(FQ_RESOURCE_PATH, getClass().getClassLoader())); + } + + @Test + public void getDescriptionWithStringConstructor() { + assertDescriptionContainsExpectedPath(new ClassPathResource(FQ_RESOURCE_PATH), FQ_RESOURCE_PATH); + } + + @Test + public void getDescriptionWithStringConstructorAndLeadingSlash() { + assertDescriptionContainsExpectedPath(new ClassPathResource(FQ_RESOURCE_PATH_WITH_LEADING_SLASH), + FQ_RESOURCE_PATH); + } + + @Test + public void getDescriptionWithClassLiteralConstructor() { + assertDescriptionContainsExpectedPath(new ClassPathResource(NONEXISTENT_RESOURCE_NAME, getClass()), + FQ_RESOURCE_PATH); + } + + @Test + public void getDescriptionWithClassLiteralConstructorAndLeadingSlash() { + assertDescriptionContainsExpectedPath( + new ClassPathResource(FQ_RESOURCE_PATH_WITH_LEADING_SLASH, getClass()), FQ_RESOURCE_PATH); + } + + @Test + public void getDescriptionWithClassLoaderConstructor() { + assertDescriptionContainsExpectedPath( + new ClassPathResource(FQ_RESOURCE_PATH, getClass().getClassLoader()), FQ_RESOURCE_PATH); + } + + @Test + public void getDescriptionWithClassLoaderConstructorAndLeadingSlash() { + assertDescriptionContainsExpectedPath( + new ClassPathResource(FQ_RESOURCE_PATH_WITH_LEADING_SLASH, getClass().getClassLoader()), FQ_RESOURCE_PATH); + } + + @Test + public void dropLeadingSlashForClassLoaderAccess() { + assertEquals("test.html", new ClassPathResource("/test.html").getPath()); + assertEquals("test.html", ((ClassPathResource) new ClassPathResource("").createRelative("/test.html")).getPath()); + } + + @Test + public void preserveLeadingSlashForClassRelativeAccess() { + assertEquals("/test.html", new ClassPathResource("/test.html", getClass()).getPath()); + assertEquals("/test.html", ((ClassPathResource) new ClassPathResource("", getClass()).createRelative("/test.html")).getPath()); + } + + private void assertDescriptionContainsExpectedPath(ClassPathResource resource, String expectedPath) { Matcher matcher = DESCRIPTION_PATTERN.matcher(resource.getDescription()); assertTrue(matcher.matches()); @@ -67,55 +130,4 @@ public class ClassPathResourceTests { } } - @Test - public void stringConstructorRaisesExceptionWithFullyQualifiedPath() { - assertExceptionContainsFullyQualifiedPath(new ClassPathResource(FQ_RESOURCE_PATH)); - } - - @Test - public void classLiteralConstructorRaisesExceptionWithFullyQualifiedPath() { - assertExceptionContainsFullyQualifiedPath(new ClassPathResource(NONEXISTENT_RESOURCE_NAME, this.getClass())); - } - - @Test - public void classLoaderConstructorRaisesExceptionWithFullyQualifiedPath() { - assertExceptionContainsFullyQualifiedPath(new ClassPathResource(FQ_RESOURCE_PATH, - this.getClass().getClassLoader())); - } - - @Test - public void getDescriptionWithStringConstructor() { - assertDescriptionContainsExpectedPath(new ClassPathResource(FQ_RESOURCE_PATH), FQ_RESOURCE_PATH); - } - - @Test - public void getDescriptionWithStringConstructorAndLeadingSlash() { - assertDescriptionContainsExpectedPath(new ClassPathResource(FQ_RESOURCE_PATH_WITH_LEADING_SLASH), - FQ_RESOURCE_PATH); - } - - @Test - public void getDescriptionWithClassLiteralConstructor() { - assertDescriptionContainsExpectedPath(new ClassPathResource(NONEXISTENT_RESOURCE_NAME, this.getClass()), - FQ_RESOURCE_PATH); - } - - @Test - public void getDescriptionWithClassLiteralConstructorAndLeadingSlash() { - assertDescriptionContainsExpectedPath( - new ClassPathResource(FQ_RESOURCE_PATH_WITH_LEADING_SLASH, this.getClass()), FQ_RESOURCE_PATH); - } - - @Test - public void getDescriptionWithClassLoaderConstructor() { - assertDescriptionContainsExpectedPath( - new ClassPathResource(FQ_RESOURCE_PATH, this.getClass().getClassLoader()), FQ_RESOURCE_PATH); - } - - @Test - public void getDescriptionWithClassLoaderConstructorAndLeadingSlash() { - assertDescriptionContainsExpectedPath(new ClassPathResource(FQ_RESOURCE_PATH_WITH_LEADING_SLASH, - this.getClass().getClassLoader()), FQ_RESOURCE_PATH); - } - }