mirror of
https://gitee.com/dcren/initializr.git
synced 2026-02-25 21:22:58 +08:00
Allow contributors to be filtered
This commit exposes an additional protected method in ProjectGenerator that sub-classes can override to alter the list of `@ProjectGenerationConfiguration`-annotated types that are used to load candidate contributors. Closes gh-870
This commit is contained in:
@@ -21,12 +21,9 @@ import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.context.annotation.ImportSelector;
|
||||
import org.springframework.beans.factory.support.GenericBeanDefinition;
|
||||
import org.springframework.context.support.GenericApplicationContext;
|
||||
import org.springframework.core.io.support.SpringFactoriesLoader;
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
|
||||
/**
|
||||
* Main entry point for project generation that processes a {@link ProjectDescription} by
|
||||
@@ -104,8 +101,8 @@ public class ProjectGenerator {
|
||||
public <T> T generate(ProjectDescription description, ProjectAssetGenerator<T> projectAssetGenerator)
|
||||
throws ProjectGenerationException {
|
||||
try (ProjectGenerationContext context = this.contextFactory.get()) {
|
||||
context.registerBean(ProjectDescription.class, resolve(description, context));
|
||||
context.register(CoreConfiguration.class);
|
||||
registerProjectDescription(context, description);
|
||||
registerProjectContributors(context, description);
|
||||
this.contextConsumer.accept(context);
|
||||
context.refresh();
|
||||
try {
|
||||
@@ -117,6 +114,30 @@ public class ProjectGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the {@link ProjectGenerationConfiguration} class names that should be
|
||||
* considered. By default this method will load candidates using
|
||||
* {@link SpringFactoriesLoader} with {@link ProjectGenerationConfiguration}.
|
||||
* @param description the description of the project to generate
|
||||
* @return a list of candidate configurations
|
||||
*/
|
||||
protected List<String> getCandidateProjectGenerationConfigurations(ProjectDescription description) {
|
||||
return SpringFactoriesLoader.loadFactoryNames(ProjectGenerationConfiguration.class,
|
||||
getClass().getClassLoader());
|
||||
}
|
||||
|
||||
private void registerProjectDescription(ProjectGenerationContext context, ProjectDescription description) {
|
||||
context.registerBean(ProjectDescription.class, resolve(description, context));
|
||||
}
|
||||
|
||||
private void registerProjectContributors(ProjectGenerationContext context, ProjectDescription description) {
|
||||
getCandidateProjectGenerationConfigurations(description).forEach((configurationClassName) -> {
|
||||
GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
|
||||
beanDefinition.setBeanClassName(configurationClassName);
|
||||
context.registerBeanDefinition(configurationClassName, beanDefinition);
|
||||
});
|
||||
}
|
||||
|
||||
private Supplier<ProjectDescription> resolve(ProjectDescription description, ProjectGenerationContext context) {
|
||||
return () -> {
|
||||
if (description instanceof MutableProjectDescription) {
|
||||
@@ -134,30 +155,4 @@ public class ProjectGenerator {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link Configuration} class that registers all available
|
||||
* {@link ProjectGenerationConfiguration} classes.
|
||||
*/
|
||||
@Configuration
|
||||
@Import(ProjectGenerationImportSelector.class)
|
||||
static class CoreConfiguration {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link ImportSelector} for loading classes configured in {@code spring.factories}
|
||||
* using the
|
||||
* {@code io.spring.initializr.generator.project.ProjectGenerationConfiguration} key.
|
||||
*/
|
||||
static class ProjectGenerationImportSelector implements ImportSelector {
|
||||
|
||||
@Override
|
||||
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
|
||||
List<String> factories = SpringFactoriesLoader.loadFactoryNames(ProjectGenerationConfiguration.class,
|
||||
getClass().getClassLoader());
|
||||
return factories.toArray(new String[0]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -17,10 +17,16 @@
|
||||
package io.spring.initializr.generator.project;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import io.spring.initializr.generator.buildsystem.maven.MavenBuildSystem;
|
||||
import io.spring.initializr.generator.project.contributor.TestProjectGenerationConfiguration;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
import org.mockito.InOrder;
|
||||
|
||||
import org.springframework.beans.factory.support.BeanDefinitionOverrideException;
|
||||
@@ -166,6 +172,27 @@ public class ProjectGeneratorTests {
|
||||
assertThat(candidates).containsOnly(entry("testBean", "duplicate"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void generateCanBeExtendedToFilterProjectContributors(@TempDir Path projectDir) {
|
||||
ProjectDescription description = mock(ProjectDescription.class);
|
||||
given(description.getArtifactId()).willReturn("test-custom-contributor");
|
||||
given(description.getBuildSystem()).willReturn(new MavenBuildSystem());
|
||||
ProjectGenerator generator = new ProjectGenerator(mockContextInitializr()) {
|
||||
@Override
|
||||
protected List<String> getCandidateProjectGenerationConfigurations(ProjectDescription description) {
|
||||
assertThat(description).isSameAs(description);
|
||||
return Collections.singletonList(TestProjectGenerationConfiguration.class.getName());
|
||||
}
|
||||
};
|
||||
DefaultProjectAssetGenerator assetGenerator = new DefaultProjectAssetGenerator((desc) -> projectDir);
|
||||
Path outputDir = generator.generate(description, assetGenerator);
|
||||
Path expectedFile = outputDir.resolve("artifact-id.txt");
|
||||
assertThat(expectedFile).isRegularFile();
|
||||
assertThat(expectedFile).hasContent("test-custom-contributor");
|
||||
verify(description).getArtifactId();
|
||||
verify(description).getBuildSystem();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Consumer<ProjectGenerationContext> mockContextInitializr() {
|
||||
return mock(Consumer.class);
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* 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.
|
||||
* 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 io.spring.initializr.generator.project.contributor;
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
import io.spring.initializr.generator.buildsystem.maven.MavenBuildSystem;
|
||||
import io.spring.initializr.generator.condition.ConditionalOnBuildSystem;
|
||||
import io.spring.initializr.generator.project.ProjectDescription;
|
||||
import io.spring.initializr.generator.project.ProjectGenerationConfiguration;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
|
||||
/**
|
||||
* Test contributors.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
@ProjectGenerationConfiguration
|
||||
public class TestProjectGenerationConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnBuildSystem(MavenBuildSystem.ID)
|
||||
public ProjectContributor testArtifactIdContributor(ProjectDescription description) {
|
||||
return (projectRoot) -> {
|
||||
Path testFile = projectRoot.resolve("artifact-id.txt");
|
||||
Files.createFile(testFile);
|
||||
FileCopyUtils.copy(description.getArtifactId(), Files.newBufferedWriter(testFile));
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user