Support loading of base64 encoded values as Resources
An ApplicationResourceLoader has been introduced to support loading resources using registered ProtocolResolvers. All usages of DefaultResourceLoader and ResourceUtils have been changed to use the ApplicationResourceLoader. A Base64ProtocolResolver has been added to support resources of type `base64:` that contain base64 encoded values. Closes gh-36033
This commit is contained in:
committed by
Scott Frederick
parent
558d811b0a
commit
0962025c4b
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2022-2023 the original author or authors.
|
||||
* Copyright 2022-2024 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,12 +26,16 @@ import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.tngtech.archunit.base.DescribedPredicate;
|
||||
import com.tngtech.archunit.core.domain.JavaCall;
|
||||
import com.tngtech.archunit.core.domain.JavaClass;
|
||||
import com.tngtech.archunit.core.domain.JavaClass.Predicates;
|
||||
import com.tngtech.archunit.core.domain.JavaClasses;
|
||||
import com.tngtech.archunit.core.domain.JavaMethod;
|
||||
import com.tngtech.archunit.core.domain.JavaParameter;
|
||||
import com.tngtech.archunit.core.domain.properties.CanBeAnnotated;
|
||||
import com.tngtech.archunit.core.domain.properties.HasName;
|
||||
import com.tngtech.archunit.core.domain.properties.HasOwner.Predicates.With;
|
||||
import com.tngtech.archunit.core.domain.properties.HasParameterTypes;
|
||||
import com.tngtech.archunit.core.importer.ClassFileImporter;
|
||||
import com.tngtech.archunit.lang.ArchCondition;
|
||||
import com.tngtech.archunit.lang.ArchRule;
|
||||
@@ -58,11 +62,14 @@ import org.gradle.api.tasks.PathSensitivity;
|
||||
import org.gradle.api.tasks.SkipWhenEmpty;
|
||||
import org.gradle.api.tasks.TaskAction;
|
||||
|
||||
import org.springframework.util.ResourceUtils;
|
||||
|
||||
/**
|
||||
* {@link Task} that checks for architecture problems.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @author Yanming Zhou
|
||||
* @author Scott Frederick
|
||||
*/
|
||||
public abstract class ArchitectureCheck extends DefaultTask {
|
||||
|
||||
@@ -75,7 +82,8 @@ public abstract class ArchitectureCheck extends DefaultTask {
|
||||
allBeanFactoryPostProcessorBeanMethodsShouldBeStaticAndHaveNoParameters(),
|
||||
noClassesShouldCallStepVerifierStepVerifyComplete(),
|
||||
noClassesShouldConfigureDefaultStepVerifierTimeout(), noClassesShouldCallCollectorsToList(),
|
||||
noClassesShouldCallURLEncoderWithStringEncoding(), noClassesShouldCallURLDecoderWithStringEncoding());
|
||||
noClassesShouldCallURLEncoderWithStringEncoding(), noClassesShouldCallURLDecoderWithStringEncoding(),
|
||||
noClassesShouldLoadResourcesUsingResourceUtils());
|
||||
getRuleDescriptions().set(getRules().map((rules) -> rules.stream().map(ArchRule::getDescription).toList()));
|
||||
}
|
||||
|
||||
@@ -208,6 +216,18 @@ public abstract class ArchitectureCheck extends DefaultTask {
|
||||
.because("java.net.URLDecoder.decode(String s, Charset charset) should be used instead");
|
||||
}
|
||||
|
||||
private ArchRule noClassesShouldLoadResourcesUsingResourceUtils() {
|
||||
return ArchRuleDefinition.noClasses()
|
||||
.should()
|
||||
.callMethodWhere(JavaCall.Predicates.target(With.owner(Predicates.type(ResourceUtils.class)))
|
||||
.and(JavaCall.Predicates.target(HasName.Predicates.name("getURL")))
|
||||
.and(JavaCall.Predicates.target(HasParameterTypes.Predicates.rawParameterTypes(String.class)))
|
||||
.or(JavaCall.Predicates.target(With.owner(Predicates.type(ResourceUtils.class)))
|
||||
.and(JavaCall.Predicates.target(HasName.Predicates.name("getFile")))
|
||||
.and(JavaCall.Predicates.target(HasParameterTypes.Predicates.rawParameterTypes(String.class)))))
|
||||
.because("org.springframework.boot.io.ApplicationResourceLoader should be used instead");
|
||||
}
|
||||
|
||||
public void setClasses(FileCollection classes) {
|
||||
this.classes = classes;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
* Copyright 2012-2024 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.
|
||||
@@ -36,6 +36,7 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
* Tests for {@link ArchitectureCheck}.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @author Scott Frederick
|
||||
*/
|
||||
class ArchitectureCheckTests {
|
||||
|
||||
@@ -121,6 +122,22 @@ class ArchitectureCheckTests {
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenClassLoadsResourceUsingResourceUtilsTaskFailsAndWritesReport() throws Exception {
|
||||
prepareTask("resources/loads", (architectureCheck) -> {
|
||||
assertThatExceptionOfType(GradleException.class).isThrownBy(architectureCheck::checkArchitecture);
|
||||
assertThat(failureReport(architectureCheck)).isNotEmpty();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenClassUsesResourceUtilsWithoutLoadingResourcesTaskSucceedsAndWritesAnEmptyReport() throws Exception {
|
||||
prepareTask("resources/noloads", (architectureCheck) -> {
|
||||
architectureCheck.checkArchitecture();
|
||||
assertThat(failureReport(architectureCheck)).isEmpty();
|
||||
});
|
||||
}
|
||||
|
||||
private void prepareTask(String classes, Callback<ArchitectureCheck> callback) throws Exception {
|
||||
File projectDir = new File(this.temp, "project");
|
||||
projectDir.mkdirs();
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright 2012-2024 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.build.architecture.resources.loads;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
|
||||
import org.springframework.util.ResourceUtils;
|
||||
|
||||
public class ResourceUtilsResourceLoader {
|
||||
|
||||
void getResource() throws FileNotFoundException {
|
||||
ResourceUtils.getURL("gradle.properties");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2012-2024 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.build.architecture.resources.noloads;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
|
||||
import org.springframework.util.ResourceUtils;
|
||||
|
||||
public class ResourceUtilsWithoutLoading {
|
||||
|
||||
void inspectResourceLocation() throws MalformedURLException {
|
||||
ResourceUtils.isUrl("gradle.properties");
|
||||
ResourceUtils.isFileURL(new URL("gradle.properties"));
|
||||
"test".startsWith(ResourceUtils.FILE_URL_PREFIX);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user