diff --git a/initializr-generator/pom.xml b/initializr-generator/pom.xml
index 9d39cb9c..232bd4f7 100644
--- a/initializr-generator/pom.xml
+++ b/initializr-generator/pom.xml
@@ -49,6 +49,11 @@
xmlunittest
+
+ org.springframework.boot
+ spring-boot-configuration-processor
+ true
+
@@ -64,10 +69,6 @@
-
- org.codehaus.gmavenplus
- gmavenplus-plugin
-
diff --git a/initializr-generator/src/main/groovy/io/spring/initializr/generator/BasicProjectRequest.groovy b/initializr-generator/src/main/groovy/io/spring/initializr/generator/BasicProjectRequest.groovy
deleted file mode 100644
index 6d52aa48..00000000
--- a/initializr-generator/src/main/groovy/io/spring/initializr/generator/BasicProjectRequest.groovy
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright 2012-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.
- * You may obtain a copy of the License at
- *
- * http://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
-
-/**
- * The base settings of a project request. Only these can be bound by user's
- * input.
- *
- * @author Stephane Nicoll
- */
-class BasicProjectRequest {
-
- List style = []
- List dependencies = []
- String name
- String type
- String description
- String groupId
- String artifactId
- String version
- String bootVersion
- String packaging
- String applicationName
- String language
- String packageName
- String javaVersion
-
- // The base directory to create in the archive - no baseDir by default
- String baseDir
-
-}
diff --git a/initializr-generator/src/main/groovy/io/spring/initializr/generator/CommandLineHelpGenerator.groovy b/initializr-generator/src/main/groovy/io/spring/initializr/generator/CommandLineHelpGenerator.groovy
deleted file mode 100644
index 5324634d..00000000
--- a/initializr-generator/src/main/groovy/io/spring/initializr/generator/CommandLineHelpGenerator.groovy
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
- * Copyright 2012-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.
- * You may obtain a copy of the License at
- *
- * http://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
-
-import io.spring.initializr.metadata.InitializrMetadata
-import io.spring.initializr.metadata.Type
-import io.spring.initializr.util.GroovyTemplate
-
-/**
- * Generate help pages for command-line clients.
- *
- * @author Stephane Nicoll
- */
-class CommandLineHelpGenerator {
-
- private static final String logo = '''
- . ____ _ __ _ _
- /\\\\ / ___'_ __ _ _(_)_ __ __ _ \\ \\ \\ \\
-( ( )\\___ | '_ | '_| | '_ \\/ _` | \\ \\ \\ \\
- \\\\/ ___)| |_)| | | | | || (_| | ) ) ) )
- ' |____| .__|_| |_|_| |_\\__, | / / / /
- =========|_|==============|___/=/_/_/_/
- '''
-
- private final GroovyTemplate template
-
- CommandLineHelpGenerator(GroovyTemplate template) {
- this.template = template
- }
-
- /**
- * Generate the capabilities of the service as a generic plain text
- * document. Used when no particular agent was detected.
- */
- String generateGenericCapabilities(InitializrMetadata metadata, String serviceUrl) {
- def model = initializeCommandLineModel(metadata, serviceUrl)
- model['hasExamples'] = false
- template.process 'cli-capabilities.txt', model
- }
-
- /**
- * Generate the capabilities of the service using "curl" as a plain text
- * document.
- */
- String generateCurlCapabilities(InitializrMetadata metadata, String serviceUrl) {
- def model = initializeCommandLineModel(metadata, serviceUrl)
- model['examples'] = template.process 'curl-examples.txt', model
- model['hasExamples'] = true
- template.process 'cli-capabilities.txt', model
- }
-
- /**
- * Generate the capabilities of the service using "HTTPie" as a plain text
- * document.
- */
- String generateHttpieCapabilities(InitializrMetadata metadata, String serviceUrl) {
- def model = initializeCommandLineModel(metadata, serviceUrl)
- model['examples'] = template.process 'httpie-examples.txt', model
- model['hasExamples'] = true
- template.process 'cli-capabilities.txt', model
- }
-
- /**
- * Generate the capabilities of the service using Spring Boot CLI as a plain
- * text document.
- */
- String generateSpringBootCliCapabilities(InitializrMetadata metadata, String serviceUrl) {
- def model = initializeSpringBootCliModel(metadata, serviceUrl)
- model['hasExamples'] = false
- template.process('boot-cli-capabilities.txt', model)
- }
-
- protected Map initializeCommandLineModel(InitializrMetadata metadata, serviceUrl) {
- Map model = [:]
- model['logo'] = logo
- model['serviceUrl'] = serviceUrl
- model['dependencies'] = generateDependencyTable(metadata)
- model['types'] = generateTypeTable(metadata, 'Rel', false)
-
- Map defaults = metadata.defaults()
- defaults['applicationName'] = metadata.configuration.generateApplicationName(metadata.name.content)
- defaults['baseDir'] = 'no base dir'
- defaults['dependencies'] = 'none'
-
- Map parametersDescription = buildParametersDescription(metadata)
- String[][] parameterTable = new String[defaults.size() + 1][];
- parameterTable[0] = ["Parameter", "Description", "Default value"]
- defaults.sort().keySet().eachWithIndex { id, i ->
- String[] data = new String[3]
- data[0] = id
- data[1] = parametersDescription[id]
- data[2] = defaults[id]
- parameterTable[i + 1] = data
- }
- model['parameters'] = TableGenerator.generate(parameterTable)
-
- model
- }
-
- protected Map initializeSpringBootCliModel(InitializrMetadata metadata, serviceUrl) {
- Map model = [:]
- model['logo'] = logo
- model['serviceUrl'] = serviceUrl
- model['dependencies'] = generateDependencyTable(metadata)
- model['types'] = generateTypeTable(metadata, 'Id', true)
-
-
- Map defaults = metadata.defaults()
- Map parametersDescription = buildParametersDescription(metadata)
- String[][] parameterTable = new String[defaults.size() + 1][];
- parameterTable[0] = ["Id", "Description", "Default value"]
- defaults.keySet().eachWithIndex { id, i ->
- String[] data = new String[3]
- data[0] = id
- data[1] = parametersDescription[id]
- data[2] = defaults[id]
- parameterTable[i + 1] = data
- }
- model['parameters'] = TableGenerator.generate(parameterTable)
- model
- }
-
- protected String generateDependencyTable(InitializrMetadata metadata) {
- String[][] dependencyTable = new String[metadata.dependencies.all.size() + 1][];
- dependencyTable[0] = ["Id", "Description", "Required version"]
- new ArrayList(metadata.dependencies.all).sort { a, b -> a.id <=> b.id }
- .eachWithIndex { dep, i ->
- String[] data = new String[3]
- data[0] = dep.id
- data[1] = dep.description ?: dep.name
- data[2] = dep.versionRequirement
- dependencyTable[i + 1] = data
- }
- TableGenerator.generate(dependencyTable)
- }
-
- protected String generateTypeTable(InitializrMetadata metadata, String linkHeader, boolean addTags) {
- String[][] typeTable = new String[metadata.types.content.size() + 1][];
- if (addTags) {
- typeTable[0] = [linkHeader, "Description", "Tags"]
- }
- else {
- typeTable[0] = [linkHeader, "Description"]
- }
- new ArrayList<>(metadata.types.content).sort { a, b -> a.id <=> b.id }.eachWithIndex { type, i ->
- String[] data = new String[typeTable[0].length]
- data[0] = (type.default ? type.id + " *" : type.id)
- data[1] = type.description ?: type.name
- if (addTags) {
- data[2] = buildTagRepresentation(type)
- }
- typeTable[i + 1] = data;
- }
- TableGenerator.generate(typeTable)
- }
-
- protected Map buildParametersDescription(InitializrMetadata metadata) {
- Map result = [:]
- metadata.properties.each { key, value ->
- if (value.hasProperty('description') && value.hasProperty('id')) {
- result[value.id] = value['description']
- }
- }
- result['applicationName'] = 'application name'
- result['baseDir'] = 'base directory to create in the archive'
- result
- }
-
- private static String buildTagRepresentation(Type type) {
- if (type.tags.isEmpty()) {
- return "";
- }
- type.tags.collect { key, value ->
- "$key:$value"
- }.join(",")
- }
-
- private static class TableGenerator {
-
- static final String NEW_LINE = System.getProperty("line.separator")
-
- /**
- * Generate a table description for the specified {@code content}.
- *
- * The {@code content} is a two-dimensional array holding the rows
- * of the table. The first entry holds the header of the table.
- */
- public static String generate(String[][] content) {
- StringBuilder sb = new StringBuilder()
- int[] columnsLength = computeColumnsLength(content)
- appendTableSeparation(sb, columnsLength)
- appendRow(sb, content, columnsLength, 0) // Headers
- appendTableSeparation(sb, columnsLength)
- for (int i = 1; i < content.length; i++) {
- appendRow(sb, content, columnsLength, i)
- }
- appendTableSeparation(sb, columnsLength)
- sb.toString()
- }
-
-
- private static void appendRow(StringBuilder sb, String[][] content,
- int[] columnsLength, int rowIndex) {
- String[] row = content[rowIndex]
- for (int i = 0; i < row.length; i++) {
- sb.append("| ").append(fill(row[i], columnsLength[i])).append(" ")
- }
- sb.append("|")
- sb.append(NEW_LINE)
- }
-
- private static void appendTableSeparation(StringBuilder sb, int[] headersLength) {
- for (int headerLength : headersLength) {
- sb.append("+").append("-".multiply(headerLength + 2))
- }
- sb.append("+")
- sb.append(NEW_LINE)
- }
-
- private static String fill(String data, int columnSize) {
- if (data == null) {
- return " ".multiply(columnSize)
- } else {
- int i = columnSize - data.length()
- return data + " ".multiply(i)
- }
- }
-
- private static int[] computeColumnsLength(String[][] content) {
- int count = content[0].length
- int[] result = new int[count]
- for (int i = 0; i < count; i++) {
- result[i] = largest(content, i)
- }
- return result
- }
-
- private static int largest(String[][] content, int column) {
- int max = 0
- for (String[] rows : content) {
- String s = rows[column]
- if (s && s.length() > max) {
- max = s.length()
- }
- }
- return max
- }
-
- }
-
-}
diff --git a/initializr-generator/src/main/groovy/io/spring/initializr/generator/ProjectGenerator.groovy b/initializr-generator/src/main/groovy/io/spring/initializr/generator/ProjectGenerator.groovy
deleted file mode 100644
index eadb5927..00000000
--- a/initializr-generator/src/main/groovy/io/spring/initializr/generator/ProjectGenerator.groovy
+++ /dev/null
@@ -1,444 +0,0 @@
-/*
- * Copyright 2012-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.
- * You may obtain a copy of the License at
- *
- * http://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
-
-import groovy.util.logging.Slf4j
-import io.spring.initializr.InitializrException
-import io.spring.initializr.metadata.Dependency
-import io.spring.initializr.metadata.InitializrMetadataProvider
-import io.spring.initializr.util.GroovyTemplate
-import io.spring.initializr.util.Version
-
-import org.springframework.beans.factory.annotation.Autowired
-import org.springframework.beans.factory.annotation.Value
-import org.springframework.context.ApplicationEventPublisher
-import org.springframework.util.Assert
-
-import static io.spring.initializr.metadata.InitializrConfiguration.Env.Maven.ParentPom
-
-/**
- * Generate a project based on the configured metadata.
- *
- * @author Dave Syer
- * @author Stephane Nicoll
- * @author Sebastien Deleuze
- */
-@Slf4j
-class ProjectGenerator {
-
- private static final VERSION_1_2_0_RC1 = Version.parse('1.2.0.RC1')
-
- private static final VERSION_1_3_0_M1 = Version.parse('1.3.0.M1')
-
- private static final VERSION_1_4_0_M2 = Version.parse('1.4.0.M2')
-
- private static final VERSION_1_4_0_M3 = Version.parse('1.4.0.M3')
-
- private static final VERSION_1_4_2_M1 = Version.parse('1.4.2.M1')
-
- private static final VERSION_2_0_0_M1 = Version.parse('2.0.0.M1')
-
- @Autowired
- ApplicationEventPublisher eventPublisher
-
- @Autowired
- InitializrMetadataProvider metadataProvider
-
- @Autowired
- ProjectRequestResolver requestResolver
-
- @Autowired
- GroovyTemplate groovyTemplate = new GroovyTemplate()
-
- @Autowired
- ProjectResourceLocator projectResourceLocator = new ProjectResourceLocator()
-
- @Value('${TMPDIR:.}/initializr')
- String tmpdir
-
- private File temporaryDirectory
- private transient Map> temporaryFiles = [:]
-
- /**
- * Generate a Maven pom for the specified {@link ProjectRequest}.
- */
- byte[] generateMavenPom(ProjectRequest request) {
- try {
- def model = resolveModel(request)
- if (!isMavenBuild(request)) {
- throw new InvalidProjectRequestException("Could not generate Maven pom, " +
- "invalid project type $request.type")
- }
- def content = doGenerateMavenPom(model)
- publishProjectGeneratedEvent(request)
- content
- } catch (InitializrException ex) {
- publishProjectFailedEvent(request, ex)
- throw ex
- }
- }
-
- /**
- * Generate a Gradle build file for the specified {@link ProjectRequest}.
- */
- byte[] generateGradleBuild(ProjectRequest request) {
- try {
- def model = resolveModel(request)
- if (!isGradleBuild(request)) {
- throw new InvalidProjectRequestException("Could not generate Gradle build, " +
- "invalid project type $request.type")
- }
- def content = doGenerateGradleBuild(model)
- publishProjectGeneratedEvent(request)
- content
- } catch (InitializrException ex) {
- publishProjectFailedEvent(request, ex)
- throw ex
- }
- }
-
- /**
- * Generate a project structure for the specified {@link ProjectRequest}. Returns
- * a directory containing the project.
- */
- File generateProjectStructure(ProjectRequest request) {
- try {
- doGenerateProjectStructure(request)
- } catch (InitializrException ex) {
- publishProjectFailedEvent(request, ex)
- throw ex
- }
- }
-
- protected File doGenerateProjectStructure(ProjectRequest request) {
- def model = resolveModel(request)
-
- def rootDir = File.createTempFile('tmp', '', getTemporaryDirectory())
- addTempFile(rootDir.name, rootDir)
- rootDir.delete()
- rootDir.mkdirs()
-
- def dir = initializerProjectDir(rootDir, request)
-
- if (isGradleBuild(request)) {
- def gradle = new String(doGenerateGradleBuild(model))
- new File(dir, 'build.gradle').write(gradle)
- writeGradleWrapper(dir, Version.safeParse(request.bootVersion))
- } else {
- def pom = new String(doGenerateMavenPom(model))
- new File(dir, 'pom.xml').write(pom)
- writeMavenWrapper(dir)
- }
-
- generateGitIgnore(dir, request)
-
- def applicationName = request.applicationName
- def language = request.language
-
- String codeLocation = language
- def src = new File(new File(dir, "src/main/$codeLocation"), request.packageName.replace('.', '/'))
- src.mkdirs()
- def extension = (language.equals('kotlin') ? 'kt' : language)
- write(new File(src, "${applicationName}.${extension}"), "Application.$extension", model)
-
- if (request.packaging == 'war') {
- def fileName = "ServletInitializer.$extension"
- write(new File(src, fileName), fileName, model)
- }
-
- def test = new File(new File(dir, "src/test/$codeLocation"), request.packageName.replace('.', '/'))
- test.mkdirs()
- setupTestModel(request, model)
- write(new File(test, "${applicationName}Tests.${extension}"), "ApplicationTests.$extension", model)
-
- def resources = new File(dir, 'src/main/resources')
- resources.mkdirs()
- new File(resources, 'application.properties').write('')
-
- if (request.hasWebFacet()) {
- new File(dir, 'src/main/resources/templates').mkdirs()
- new File(dir, 'src/main/resources/static').mkdirs()
- }
- publishProjectGeneratedEvent(request)
- rootDir
-
- }
-
- /**
- * Create a distribution file for the specified project structure
- * directory and extension
- */
- File createDistributionFile(File dir, String extension) {
- def download = new File(getTemporaryDirectory(), dir.name + extension)
- addTempFile(dir.name, download)
- download
- }
-
- private File getTemporaryDirectory() {
- if (!temporaryDirectory) {
- temporaryDirectory = new File(tmpdir, 'initializr')
- temporaryDirectory.mkdirs()
- }
- temporaryDirectory
- }
-
- /**
- * Clean all the temporary files that are related to this root
- * directory.
- * @see #createDistributionFile
- */
- void cleanTempFiles(File dir) {
- def tempFiles = temporaryFiles.remove(dir.name)
- if (tempFiles) {
- tempFiles.each { File file ->
- if (file.directory) {
- file.deleteDir()
- } else {
- file.delete()
- }
- }
- }
- }
-
- private void publishProjectGeneratedEvent(ProjectRequest request) {
- ProjectGeneratedEvent event = new ProjectGeneratedEvent(request)
- eventPublisher.publishEvent(event)
- }
-
- private void publishProjectFailedEvent(ProjectRequest request, Exception cause) {
- ProjectFailedEvent event = new ProjectFailedEvent(request, cause)
- eventPublisher.publishEvent(event)
- }
-
- /**
- * Generate a {@code .gitignore} file for the specified {@link ProjectRequest}
- * @param dir the root directory of the project
- * @param request the request to handle
- */
- protected void generateGitIgnore(File dir, ProjectRequest request) {
- def model = [:]
- model['build'] = isGradleBuild(request) ? 'gradle' : 'maven'
- write(new File(dir, '.gitignore'), 'gitignore.tmpl', model)
- }
-
- /**
- * Resolve the specified {@link ProjectRequest} and return the model to use
- * to generate the project
- * @param request the request to handle
- * @return a model for that request
- */
- protected Map resolveModel(ProjectRequest originalRequest) {
- Assert.notNull originalRequest.bootVersion, 'boot version must not be null'
- def model = [:]
- def metadata = metadataProvider.get()
-
- ProjectRequest request = requestResolver.resolve(originalRequest, metadata)
-
- // request resolved so we can log what has been requested
- def dependencies = request.resolvedDependencies
- def dependencyIds = dependencies.collect { it.id }
- log.info("Processing request{type=$request.type, dependencies=$dependencyIds}")
-
- if (isMavenBuild(request)) {
- ParentPom parentPom = metadata.configuration.env.maven.resolveParentPom(request.bootVersion)
- if (parentPom.includeSpringBootBom && !request.boms['spring-boot']) {
- request.boms['spring-boot'] = metadata.createSpringBootBom(
- request.bootVersion, 'spring-boot.version')
- }
-
- model['mavenParentGroupId'] = parentPom.groupId
- model['mavenParentArtifactId'] = parentPom.artifactId
- model['mavenParentVersion'] = parentPom.version
- model['includeSpringBootBom'] = parentPom.includeSpringBootBom
- }
-
- model['resolvedBoms'] = request.boms.values().sort {a, b -> a.order <=> b.order }
-
- model['compileDependencies'] = filterDependencies(dependencies, Dependency.SCOPE_COMPILE)
- model['runtimeDependencies'] = filterDependencies(dependencies, Dependency.SCOPE_RUNTIME)
- model['compileOnlyDependencies'] = filterDependencies(dependencies, Dependency.SCOPE_COMPILE_ONLY)
- model['providedDependencies'] = filterDependencies(dependencies, Dependency.SCOPE_PROVIDED)
- model['testDependencies'] = filterDependencies(dependencies, Dependency.SCOPE_TEST)
-
- request.boms.each { k, v ->
- if (v.versionProperty) {
- request.buildProperties.versions[v.versionProperty] = { v.version }
- }
- }
-
- // Add various versions
- model['dependencyManagementPluginVersion'] = metadata.configuration.env.gradle.dependencyManagementPluginVersion
- model['kotlinVersion'] = metadata.configuration.env.kotlin.version
-
- // @SpringBootApplication available as from 1.2.0.RC1
- model['useSpringBootApplication'] = VERSION_1_2_0_RC1
- .compareTo(Version.safeParse(request.bootVersion)) <= 0
-
- // Gradle plugin has changed as from 1.3.0
- model['bootOneThreeAvailable'] = VERSION_1_3_0_M1
- .compareTo(Version.safeParse(request.bootVersion)) <= 0
-
- // Gradle plugin has changed again as from 1.4.2
- model['springBootPluginName'] = (VERSION_1_4_2_M1.compareTo(
- Version.safeParse(request.bootVersion)) <= 0 ? 'org.springframework.boot' : 'spring-boot')
-
- // New testing stuff
- model['newTestInfrastructure'] = isNewTestInfrastructureAvailable(request)
-
- // New Servlet Initializer location
- model['newServletInitializer'] = isNewServletInitializerAvailable(request)
-
- // Append the project request to the model
- request.properties.each { model[it.key] = it.value }
-
- model
- }
-
- protected void setupTestModel(ProjectRequest request, Map model) {
- String imports = ''
- String testAnnotations = ''
- def newTestInfrastructure = isNewTestInfrastructureAvailable(request)
- if (newTestInfrastructure) {
- imports += String.format(generateImport('org.springframework.boot.test.context.SpringBootTest',
- request.language) + "%n")
- imports += String.format(generateImport('org.springframework.test.context.junit4.SpringRunner',
- request.language) + "%n")
- } else {
- imports += String.format(generateImport('org.springframework.boot.test.SpringApplicationConfiguration',
- request.language) + "%n")
- imports += String.format(generateImport('org.springframework.test.context.junit4.SpringJUnit4ClassRunner',
- request.language) + "%n")
- }
- if (request.hasWebFacet() && !newTestInfrastructure) {
- imports += String.format(generateImport('org.springframework.test.context.web.WebAppConfiguration',
- request.language) + "%n")
- testAnnotations = String.format('@WebAppConfiguration%n')
- }
- model.testImports = imports
- model.testAnnotations = testAnnotations
- }
-
- protected String generateImport(String type, String language) {
- String end = (language.equals("groovy") || language.equals("kotlin")) ? '' : ';'
- "import $type$end"
- }
-
- private static isGradleBuild(ProjectRequest request) {
- return 'gradle'.equals(request.build)
- }
-
- private static isMavenBuild(ProjectRequest request) {
- return 'maven'.equals(request.build)
- }
-
- private static boolean isNewTestInfrastructureAvailable(ProjectRequest request) {
- VERSION_1_4_0_M2
- .compareTo(Version.safeParse(request.bootVersion)) <= 0
- }
-
- private static boolean isNewServletInitializerAvailable(ProjectRequest request) {
- VERSION_1_4_0_M3
- .compareTo(Version.safeParse(request.bootVersion)) <= 0
- }
-
- private static boolean isGradle3Available(Version bootVersion) {
- VERSION_2_0_0_M1.compareTo(bootVersion) <= 0
- }
-
- private byte[] doGenerateMavenPom(Map model) {
- groovyTemplate.process 'starter-pom.xml', model
- }
-
-
- private byte[] doGenerateGradleBuild(Map model) {
- groovyTemplate.process 'starter-build.gradle', model
- }
-
- private void writeGradleWrapper(File dir, Version bootVersion) {
- String gradlePrefix = isGradle3Available(bootVersion) ? 'gradle3' : 'gradle'
- writeTextResource(dir, 'gradlew.bat', "$gradlePrefix/gradlew.bat")
- writeTextResource(dir, 'gradlew', "$gradlePrefix/gradlew")
-
- def wrapperDir = new File(dir, 'gradle/wrapper')
- wrapperDir.mkdirs()
- writeTextResource(wrapperDir, 'gradle-wrapper.properties',
- "$gradlePrefix/gradle/wrapper/gradle-wrapper.properties")
- writeBinaryResource(wrapperDir, 'gradle-wrapper.jar',
- "$gradlePrefix/gradle/wrapper/gradle-wrapper.jar")
- }
-
- private void writeMavenWrapper(File dir) {
- writeTextResource(dir, 'mvnw.cmd', 'maven/mvnw.cmd')
- writeTextResource(dir, 'mvnw', 'maven/mvnw')
-
- def wrapperDir = new File(dir, '.mvn/wrapper')
- wrapperDir.mkdirs()
- writeTextResource(wrapperDir, 'maven-wrapper.properties',
- 'maven/wrapper/maven-wrapper.properties')
- writeBinaryResource(wrapperDir, 'maven-wrapper.jar',
- 'maven/wrapper/maven-wrapper.jar')
- }
-
- private File writeBinaryResource(File dir, String name, String location) {
- doWriteProjectResource(dir, name, location, true)
- }
-
- private File writeTextResource(File dir, String name, String location) {
- doWriteProjectResource(dir, name, location, false)
- }
-
- private File doWriteProjectResource(File dir, String name, String location, boolean binary) {
- def target = new File(dir, name)
- if (binary) {
- target << projectResourceLocator.getBinaryResource("classpath:project/$location")
- }
- else {
- target.write(projectResourceLocator.getTextResource("classpath:project/$location"))
- }
- target
- }
-
- private File initializerProjectDir(File rootDir, ProjectRequest request) {
- if (request.baseDir) {
- File dir = new File(rootDir, request.baseDir)
- dir.mkdirs()
- return dir
- } else {
- return rootDir
- }
- }
-
- def write(File target, String templateName, def model) {
- def tmpl = templateName.endsWith('.groovy') ? templateName + '.tmpl' : templateName
- def body = groovyTemplate.process tmpl, model
- target.write(body, 'utf-8')
- }
-
- private void addTempFile(String group, File file) {
- def content = temporaryFiles[group]
- if (!content) {
- content = []
- temporaryFiles[group] = content
- }
- content << file
- }
-
- private static def filterDependencies(def dependencies, String scope) {
- dependencies.findAll { dep -> scope.equals(dep.scope) }.sort { a, b -> a.id <=> b.id }
- }
-
-}
diff --git a/initializr-generator/src/main/groovy/io/spring/initializr/generator/ProjectRequest.groovy b/initializr-generator/src/main/groovy/io/spring/initializr/generator/ProjectRequest.groovy
deleted file mode 100644
index d26d16ef..00000000
--- a/initializr-generator/src/main/groovy/io/spring/initializr/generator/ProjectRequest.groovy
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- * Copyright 2012-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.
- * You may obtain a copy of the License at
- *
- * http://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
-
-import groovy.transform.ToString
-import groovy.util.logging.Slf4j
-import io.spring.initializr.metadata.BillOfMaterials
-import io.spring.initializr.metadata.Dependency
-import io.spring.initializr.metadata.InitializrMetadata
-import io.spring.initializr.metadata.Repository
-import io.spring.initializr.metadata.Type
-import io.spring.initializr.util.Version
-import io.spring.initializr.util.VersionRange
-
-/**
- * A request to generate a project.
- *
- * @author Dave Syer
- * @author Stephane Nicoll
- */
-@Slf4j
-@ToString(ignoreNulls = true, includePackage = false, includeNames = true)
-class ProjectRequest extends BasicProjectRequest {
-
- /**
- * The id of the starter to use if no dependency is defined.
- */
- public static final DEFAULT_STARTER = 'root_starter'
-
- /**
- * Additional parameters that can be used to further identify the request.
- */
- final Map parameters = [:]
-
- // Resolved dependencies based on the ids provided by either "style" or "dependencies"
- List resolvedDependencies
-
- final Map boms = [:]
-
- final Map repositories = [:]
-
- /**
- * Build properties.
- */
- final BuildProperties buildProperties = new BuildProperties()
-
- def facets = []
- def build
-
- /**
- * Initializes this instance with the defaults defined in the specified {@link InitializrMetadata}.
- */
- void initialize(InitializrMetadata metadata) {
- metadata.defaults().each { key, value ->
- if (owner.hasProperty(key)) {
- owner.setProperty(key, value)
- }
- }
- }
-
- /**
- * Resolve this instance against the specified {@link InitializrMetadata}
- */
- void resolve(InitializrMetadata metadata) {
- List depIds = style ? style : dependencies
- String actualBootVersion = bootVersion ?: metadata.bootVersions.default.id
- Version requestedVersion = Version.parse(actualBootVersion)
- resolvedDependencies = depIds.collect {
- def dependency = metadata.dependencies.get(it)
- if (dependency == null) {
- throw new InvalidProjectRequestException("Unknown dependency '$it' check project metadata")
- }
- dependency.resolve(requestedVersion)
- }
- resolvedDependencies.each {
- it.facets.each {
- if (!facets.contains(it)) {
- facets.add(it)
- }
- }
- if (!it.match(requestedVersion)) {
- throw new InvalidProjectRequestException("Dependency '$it.id' is not compatible " +
- "with Spring Boot $requestedVersion")
- }
- if (it.bom) {
- resolveBom(metadata, it.bom, requestedVersion)
- }
- if (it.repository) {
- String repositoryId = it.repository
- if (!repositories[repositoryId]) {
- repositories[repositoryId] = metadata.configuration.env.repositories[repositoryId]
- }
- }
- }
-
- if (this.type) {
- Type type = metadata.types.get(this.type)
- if (!type) {
- throw new InvalidProjectRequestException("Unknown type '${this.type}' check project metadata")
- }
- String buildTag = type.tags['build']
- if (buildTag) {
- this.build = buildTag
- }
- }
- if (this.packaging) {
- def packaging = metadata.packagings.get(this.packaging)
- if (!packaging) {
- throw new InvalidProjectRequestException("Unknown packaging '${this.packaging}' check project metadata")
- }
- }
- if (this.language) {
- def language = metadata.languages.get(this.language)
- if (!language) {
- throw new InvalidProjectRequestException("Unknown language '${this.language}' check project metadata")
- }
- }
-
- if (!applicationName) {
- this.applicationName = metadata.configuration.generateApplicationName(this.name)
- }
- packageName = metadata.configuration.cleanPackageName(this.packageName, metadata.packageName.content)
-
- initializeRepositories(metadata, requestedVersion)
-
- initializeProperties(metadata)
-
- afterResolution(metadata)
- }
-
- /**
- * Set the repositories that this instance should use based on the {@link InitializrMetadata}
- * and the requested Spring Boot {@link Version}.
- */
- protected void initializeRepositories(InitializrMetadata metadata, Version requestedVersion) {
- if (!'RELEASE'.equals(requestedVersion.qualifier.qualifier)) {
- repositories['spring-snapshots'] = metadata.configuration.env.repositories['spring-snapshots']
- repositories['spring-milestones'] = metadata.configuration.env.repositories['spring-milestones']
- }
- boms.values().each {
- it.repositories.each {
- if (!repositories[it]) {
- repositories[it] = metadata.configuration.env.repositories[it]
- }
- }
- }
- }
-
- protected void initializeProperties(InitializrMetadata metadata) {
- if ('gradle'.equals(build)) {
- buildProperties.gradle['springBootVersion'] = { getBootVersion() }
- if ('kotlin'.equals(language)) {
- buildProperties.gradle['kotlinVersion'] = { metadata.configuration.env.kotlin.version }
- }
- } else {
- buildProperties.maven['project.build.sourceEncoding'] = { 'UTF-8' }
- buildProperties.maven['project.reporting.outputEncoding'] = { 'UTF-8' }
- buildProperties.versions['java.version'] = { getJavaVersion() }
- if ('kotlin'.equals(language)) {
- buildProperties.versions['kotlin.version'] = { metadata.configuration.env.kotlin.version }
- }
- }
- }
-
- private void resolveBom(InitializrMetadata metadata, String bomId, Version requestedVersion) {
- if (!boms[bomId]) {
- def bom = metadata.configuration.env.boms[bomId].resolve(requestedVersion)
- boms[bomId] = bom
- bom.additionalBoms.each { id ->
- resolveBom(metadata, id, requestedVersion)
- }
- }
- }
-
- /**
- * Update this request once it has been resolved with the specified {@link InitializrMetadata}.
- */
- protected afterResolution(InitializrMetadata metadata) {
- if (packaging == 'war') {
- if (!hasWebFacet()) {
- // Need to be able to bootstrap the web app
- resolvedDependencies << metadata.dependencies.get('web')
- facets << 'web'
- }
- // Add the tomcat starter in provided scope
- def tomcat = new Dependency().asSpringBootStarter('tomcat')
- tomcat.scope = Dependency.SCOPE_PROVIDED
- resolvedDependencies << tomcat
- }
- if (!resolvedDependencies.find { it.starter }) {
- // There's no starter so we add the default one
- addDefaultDependency()
- }
- }
-
- /**
- * Add a default dependency if the project does not define any
- * dependency
- */
- protected addDefaultDependency() {
- def root = new Dependency()
- root.id = DEFAULT_STARTER
- root.asSpringBootStarter('')
- resolvedDependencies << root
- }
-
- /**
- * Specify if this request has the web facet enabled.
- */
- boolean hasWebFacet() {
- hasFacet('web')
- }
-
- /**
- * Specify if this request has the specified facet enabled
- */
- boolean hasFacet(String facet) {
- facets.contains(facet)
- }
-
-}
diff --git a/initializr-generator/src/main/groovy/io/spring/initializr/generator/ProjectRequestPostProcessorAdapter.groovy b/initializr-generator/src/main/groovy/io/spring/initializr/generator/ProjectRequestPostProcessorAdapter.groovy
deleted file mode 100644
index b6dbefe5..00000000
--- a/initializr-generator/src/main/groovy/io/spring/initializr/generator/ProjectRequestPostProcessorAdapter.groovy
+++ /dev/null
@@ -1,21 +0,0 @@
-package io.spring.initializr.generator
-
-import io.spring.initializr.metadata.InitializrMetadata
-
-/**
- * An implementation of {@link ProjectRequestPostProcessor} with empty methods allowing
- * sub-classes to override only the methods they're interested in.
- *
- * @author Stephane Nicoll
- */
-class ProjectRequestPostProcessorAdapter implements ProjectRequestPostProcessor {
-
- @Override
- void postProcessBeforeResolution(ProjectRequest request, InitializrMetadata metadata) {
- }
-
- @Override
- void postProcessAfterResolution(ProjectRequest request, InitializrMetadata metadata) {
- }
-
-}
diff --git a/initializr-generator/src/main/groovy/io/spring/initializr/generator/ProjectRequestResolver.groovy b/initializr-generator/src/main/groovy/io/spring/initializr/generator/ProjectRequestResolver.groovy
deleted file mode 100644
index 7d708c9e..00000000
--- a/initializr-generator/src/main/groovy/io/spring/initializr/generator/ProjectRequestResolver.groovy
+++ /dev/null
@@ -1,40 +0,0 @@
-package io.spring.initializr.generator
-
-import io.spring.initializr.metadata.InitializrMetadata
-
-import org.springframework.util.Assert
-
-/**
- * Resolve {@link ProjectRequest} instances, honoring callback hook points.
- *
- * @author Stephane Nicoll
- */
-class ProjectRequestResolver {
-
- private final List postProcessors
-
- ProjectRequestResolver(List postProcessors) {
- this.postProcessors = new ArrayList<>(postProcessors)
- }
-
- ProjectRequest resolve(ProjectRequest request, InitializrMetadata metadata) {
- Assert.notNull(request, "Request must not be null")
- applyPostProcessBeforeResolution(request, metadata)
- request.resolve(metadata)
- applyPostProcessAfterResolution(request, metadata)
- request
- }
-
- private void applyPostProcessBeforeResolution(ProjectRequest request, InitializrMetadata metadata) {
- for (ProjectRequestPostProcessor processor : postProcessors) {
- processor.postProcessBeforeResolution(request, metadata)
- }
- }
-
- private void applyPostProcessAfterResolution(ProjectRequest request, InitializrMetadata metadata) {
- for (ProjectRequestPostProcessor processor : postProcessors) {
- processor.postProcessAfterResolution(request, metadata)
- }
- }
-
-}
diff --git a/initializr-generator/src/main/groovy/io/spring/initializr/metadata/BillOfMaterials.groovy b/initializr-generator/src/main/groovy/io/spring/initializr/metadata/BillOfMaterials.groovy
deleted file mode 100644
index cba01d40..00000000
--- a/initializr-generator/src/main/groovy/io/spring/initializr/metadata/BillOfMaterials.groovy
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Copyright 2012-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.
- * You may obtain a copy of the License at
- *
- * http://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.metadata
-
-import com.fasterxml.jackson.annotation.JsonInclude
-import groovy.transform.ToString
-import io.spring.initializr.metadata.BillOfMaterials.Mapping;
-import io.spring.initializr.util.InvalidVersionException
-import io.spring.initializr.util.Version
-import io.spring.initializr.util.VersionParser
-import io.spring.initializr.util.VersionRange
-
-/**
- * Define a Bill Of Materials to be represented in the generated project
- * if a dependency refers to it.
- *
- * @author Stephane Nicoll
- */
-@ToString(ignoreNulls = true, excludes = 'mappings', includePackage = false)
-@JsonInclude(JsonInclude.Include.NON_DEFAULT)
-class BillOfMaterials {
-
- String groupId
- String artifactId
-
- /**
- * The version of the BOM. Can be {@code null} if it is provided via a mapping.
- */
- String version
-
- /**
- * The property to use to externalize the version of the BOM. When this is set,
- * a version property is automatically added rather than setting the version
- * in the bom declaration itself.
- */
- String versionProperty
-
- /**
- * The relative order of this BOM where lower values have higher priority. The
- * default value is {@code Integer.MAX_VALUE}, indicating lowest priority. The
- * Spring Boot dependencies bom has an order of 100.
- */
- Integer order = Integer.MAX_VALUE
-
- /**
- * The BOM(s) that should be automatically included if this BOM is required. Can be
- * {@code null} if it is provided via a mapping.
- */
- List additionalBoms = []
-
- /**
- * The repositories that are required if this BOM is required. Can be {@code null} if
- * it is provided via a mapping.
- */
- List repositories = []
-
- final List mappings = []
-
- /**
- * Determine the version placeholder to use for this instance. If a version
- * property is defined, this returns the reference for the property. Otherwise
- * this returns the plain {@link #version}
- */
- String determineVersionToken() {
- return (versionProperty ? '${' + versionProperty + '}' : version)
- }
-
- void validate() {
- if (!version && !mappings) {
- throw new InvalidInitializrMetadataException("No version available for $this");
- }
- updateVersionRange(VersionParser.DEFAULT)
- }
-
- void updateVersionRange(VersionParser versionParser) {
- mappings.each {
- try {
- it.range = versionParser.parseRange(it.versionRange)
- } catch (InvalidVersionException ex) {
- throw new InvalidInitializrMetadataException("Invalid version range $it.versionRange for $this", ex)
- }
- }
- }
-
- /**
- * Resolve this instance according to the specified Spring Boot {@link Version}. Return
- * a {@link BillOfMaterials} instance that holds the version, repositories and
- * additional BOMs to use, if any.
- */
- BillOfMaterials resolve(Version bootVersion) {
- if (!mappings) {
- return this
- }
-
- for (Mapping mapping : mappings) {
- if (mapping.range.match(bootVersion)) {
- def resolvedBom = new BillOfMaterials(groupId: groupId, artifactId: artifactId,
- version: mapping.version, versionProperty: versionProperty, order: order)
- resolvedBom.repositories += mapping.repositories ?: repositories
- resolvedBom.additionalBoms += mapping.additionalBoms ?: additionalBoms
- return resolvedBom
- }
- }
- throw new IllegalStateException("No suitable mapping was found for $this and version $bootVersion")
- }
-
- @ToString(ignoreNulls = true, includePackage = false)
- static class Mapping {
-
- String versionRange
-
- String version
-
- List repositories = []
-
- List additionalBoms = []
-
- private VersionRange range
-
- String determineVersionRangeRequirement() {
- range.toString()
- }
-
- public static Mapping create(String range, String version) {
- return new Mapping(versionRange: range, version: version);
- }
-
- public static Mapping create(String range, String version, String... repositories) {
- return new Mapping(versionRange: range, version: version, repositories: repositories);
- }
-
- }
-
- public static BillOfMaterials create(String groupId, String artifactId) {
- return new BillOfMaterials(groupId: groupId, artifactId: artifactId);
- }
-
- public static BillOfMaterials create(String groupId, String artifactId, String version) {
- return new BillOfMaterials(groupId: groupId, artifactId: artifactId, version: version);
- }
-
-}
diff --git a/initializr-generator/src/main/groovy/io/spring/initializr/metadata/DependenciesCapability.groovy b/initializr-generator/src/main/groovy/io/spring/initializr/metadata/DependenciesCapability.groovy
deleted file mode 100644
index 585cd5e3..00000000
--- a/initializr-generator/src/main/groovy/io/spring/initializr/metadata/DependenciesCapability.groovy
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright 2012-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.
- * You may obtain a copy of the License at
- *
- * http://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.metadata
-
-import io.spring.initializr.util.VersionParser
-
-/**
- * A {@link ServiceCapability} listing the available dependencies defined as a
- * {@link ServiceCapabilityType#HIERARCHICAL_MULTI_SELECT} capability.
- *
- * @author Stephane Nicoll
- */
-class DependenciesCapability extends ServiceCapability> {
-
- final List content = []
-
- private final Map indexedDependencies = [:]
-
- DependenciesCapability() {
- super('dependencies', ServiceCapabilityType.HIERARCHICAL_MULTI_SELECT,
- 'Project dependencies', 'dependency identifiers (comma-separated)')
- }
-
- /**
- * Return the {@link Dependency} with the specified id or {@code null} if
- * no such dependency exists.
- */
- Dependency get(String id) {
- indexedDependencies[id]
- }
-
- /**
- * Return all dependencies as a flat collection
- */
- Collection getAll() {
- Collections.unmodifiableCollection(indexedDependencies.values())
- }
-
- void validate() {
- index()
- }
-
- void updateVersionRange(VersionParser versionParser) {
- indexedDependencies.values().each {
- it.updateVersionRanges(versionParser)
- }
- }
-
- @Override
- void merge(List otherContent) {
- otherContent.each { group ->
- if (!content.find { group.name.equals(it.name)}) {
- content << group
- }
- }
- index()
- }
-
- private void index() {
- indexedDependencies.clear()
- content.each { group ->
- group.content.each { dependency ->
- // Apply defaults
- if (!dependency.versionRange && group.versionRange) {
- dependency.versionRange = group.versionRange
- }
- if (!dependency.bom && group.bom) {
- dependency.bom = group.bom
- }
- if (!dependency.repository && group.repository) {
- dependency.repository = group.repository
- }
-
- dependency.resolve()
- indexDependency(dependency.id, dependency)
- for (String alias : dependency.aliases) {
- indexDependency(alias, dependency)
- }
- }
- }
- }
-
- private void indexDependency(String id, Dependency dependency) {
- def existing = indexedDependencies[id]
- if (existing) {
- throw new IllegalArgumentException("Could not register $dependency another dependency " +
- "has also the '$id' id $existing");
- }
- indexedDependencies[id] = dependency
- }
-
-}
diff --git a/initializr-generator/src/main/groovy/io/spring/initializr/metadata/Dependency.groovy b/initializr-generator/src/main/groovy/io/spring/initializr/metadata/Dependency.groovy
deleted file mode 100644
index 9e62249b..00000000
--- a/initializr-generator/src/main/groovy/io/spring/initializr/metadata/Dependency.groovy
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * Copyright 2012-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.
- * You may obtain a copy of the License at
- *
- * http://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.metadata
-
-import com.fasterxml.jackson.annotation.JsonIgnore
-import com.fasterxml.jackson.annotation.JsonInclude
-import groovy.transform.AutoClone
-import groovy.transform.AutoCloneStyle
-import groovy.transform.ToString
-import io.spring.initializr.metadata.Dependency.Mapping;
-import io.spring.initializr.util.InvalidVersionException
-import io.spring.initializr.util.Version
-import io.spring.initializr.util.VersionParser
-import io.spring.initializr.util.VersionRange
-
-/**
- * Meta-data for a dependency. Each dependency has a primary identifier and an
- * arbitrary number of {@code aliases}.
- *
- * @author Stephane Nicoll
- */
-@ToString(ignoreNulls = true, includePackage = false)
-@JsonInclude(JsonInclude.Include.NON_EMPTY)
-@AutoClone(style = AutoCloneStyle.COPY_CONSTRUCTOR)
-
-class Dependency extends MetadataElement implements Describable {
- static final String SCOPE_COMPILE = 'compile'
- static final String SCOPE_COMPILE_ONLY = 'compileOnly'
- static final String SCOPE_RUNTIME = 'runtime'
- static final String SCOPE_PROVIDED = 'provided'
- static final String SCOPE_TEST = 'test'
- static final List SCOPE_ALL = [
- SCOPE_COMPILE,
- SCOPE_RUNTIME,
- SCOPE_COMPILE_ONLY,
- SCOPE_PROVIDED,
- SCOPE_TEST
- ]
-
- List aliases = []
-
- List facets = []
-
- String groupId
-
- String artifactId
-
- /**
- * The default version, can be {@code null} to indicate that the
- * version is managed by the project and does not need to be specified.
- */
- String version
-
- /**
- * The type, can be {@code null} to indicate that the default type
- * should be used (i.e. {@code jar}).
- */
- String type
-
- /**
- * Dependency mapping if an attribute of the dependency differs according to the
- * Spring Boot version. If no mapping matches, default attributes are used.
- */
- List mappings = []
-
- String scope = SCOPE_COMPILE
-
- String description
-
- String versionRange
-
- @JsonIgnore
- String versionRequirement
-
- private VersionRange range
-
- String bom
-
- String repository
-
- @JsonInclude(JsonInclude.Include.NON_DEFAULT)
- int weight
-
- /**
- * Specify if the dependency represents a "starter", i.e. the sole presence of
- * that dependency is enough to bootstrap the context.
- */
- boolean starter = true
-
- List keywords = []
-
- List links = []
-
- void setScope(String scope) {
- if (!SCOPE_ALL.contains(scope)) {
- throw new InvalidInitializrMetadataException("Invalid scope $scope must be one of $SCOPE_ALL")
- }
- this.scope = scope
- }
-
- void setVersionRange(String versionRange) {
- this.versionRange = versionRange ? versionRange.trim() : null
- }
-
- /**
- * Specify if the dependency has its coordinates set, i.e. {@code groupId}
- * and {@code artifactId}.
- */
- boolean hasCoordinates() {
- groupId && artifactId
- }
-
- /**
- * Define this dependency as a standard spring boot starter with the specified name
- *
If no name is specified, the root 'spring-boot-starter' is assumed.
- */
- Dependency asSpringBootStarter(String name) {
- groupId = 'org.springframework.boot'
- artifactId = name ? 'spring-boot-starter-' + name : 'spring-boot-starter'
- if (name) {
- id = name
- }
- this
- }
-
- /**
- * Validate the dependency and complete its state based on the
- * available information.
- */
- def resolve() {
- if (id == null) {
- if (!hasCoordinates()) {
- throw new InvalidInitializrMetadataException(
- 'Invalid dependency, should have at least an id or a groupId/artifactId pair.')
- }
- generateId()
- } else if (!hasCoordinates()) {
- // Let's build the coordinates from the id
- def st = new StringTokenizer(id, ':')
- if (st.countTokens() == 1) { // assume spring-boot-starter
- asSpringBootStarter(id)
- } else if (st.countTokens() == 2 || st.countTokens() == 3) {
- groupId = st.nextToken()
- artifactId = st.nextToken()
- if (st.hasMoreTokens()) {
- version = st.nextToken()
- }
- } else {
- throw new InvalidInitializrMetadataException(
- "Invalid dependency, id should have the form groupId:artifactId[:version] but got $id")
- }
- }
- links.forEach { l ->
- l.resolve()
- }
- updateVersionRanges(VersionParser.DEFAULT)
- }
-
- def updateVersionRanges(VersionParser versionParser) {
- if (versionRange) {
- try {
- range = versionParser.parseRange(versionRange)
- versionRequirement = range.toString()
- } catch (InvalidVersionException ex) {
- throw new InvalidInitializrMetadataException("Invalid version range '$versionRange' for " +
- "dependency with id '$id'", ex)
- }
- }
- mappings.each {
- try {
- it.range = versionParser.parseRange(it.versionRange)
- } catch (InvalidVersionException ex) {
- throw new InvalidInitializrMetadataException("Invalid version range $it.versionRange for $this", ex)
- }
- }
- }
-
- /**
- * Resolve this instance according to the specified Spring Boot {@link Version}. Return
- * a {@link Dependency} instance that has its state resolved against the specified version.
- */
- Dependency resolve(Version bootVersion) {
- for (Mapping mapping : mappings) {
- if (mapping.range.match(bootVersion)) {
- def dependency = new Dependency(this)
- dependency.groupId = mapping.groupId ? mapping.groupId : this.groupId
- dependency.artifactId = mapping.artifactId ? mapping.artifactId : this.artifactId
- dependency.version = mapping.version ? mapping.version : this.version
- dependency.versionRequirement = mapping.range.toString()
- dependency.mappings = null
- return dependency
- }
- }
- return this
- }
-
- /**
- * Specify if this dependency is available for the specified Spring Boot version.
- */
- boolean match(Version version) {
- if (range) {
- return range.match(version)
- }
- true
- }
-
- /**
- * Generate an id using the groupId and artifactId
- */
- def generateId() {
- if (groupId == null || artifactId == null) {
- throw new IllegalArgumentException(
- "Could not generate id for $this: at least groupId and artifactId must be set.")
- }
- StringBuilder sb = new StringBuilder()
- sb.append(groupId).append(':').append(artifactId)
- id = sb.toString()
- }
-
- /**
- * Map several attribute of the dependency for a given version range.
- */
- static class Mapping {
-
- /**
- * The version range of this mapping.
- */
- String versionRange
-
- /**
- * The version to use for this mapping or {@code null} to use the default.
- */
- String groupId;
-
- /**
- * The groupId to use for this mapping or {@code null} to use the default.
- */
- String artifactId;
-
- /**
- * The artifactId to use for this mapping or {@code null} to use the default.
- */
- String version
-
- private VersionRange range
-
- public static Mapping create(String range, String groupId, String artifactId,
- String version) {
- new Mapping(versionRange: range, groupId: groupId, artifactId: artifactId, version: version);
- }
- }
-
- public static Dependency create(String groupId, String artifactId, String version, String scope) {
- return new Dependency(groupId: groupId, artifactId: artifactId, version: version, scope: scope);
- }
-
- public static Dependency withId(String id, String groupId, String artifactId, String version) {
- return new Dependency(groupId: groupId, artifactId: artifactId, versionRange: version, id: id);
- }
-
- public static Dependency withId(String id, String groupId, String artifactId) {
- return new Dependency(groupId: groupId, artifactId: artifactId, id: id);
- }
-
-}
diff --git a/initializr-generator/src/main/groovy/io/spring/initializr/metadata/DependencyMetadata.groovy b/initializr-generator/src/main/groovy/io/spring/initializr/metadata/DependencyMetadata.groovy
deleted file mode 100644
index bc47afe5..00000000
--- a/initializr-generator/src/main/groovy/io/spring/initializr/metadata/DependencyMetadata.groovy
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright 2012-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.
- * You may obtain a copy of the License at
- *
- * http://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.metadata
-
-import io.spring.initializr.util.Version
-
-/**
- * Dependency metadata for a given spring boot {@link Version}.
- *
- * @author Stephane Nicoll
- */
-class DependencyMetadata {
-
- final Version bootVersion
-
- final Map dependencies
-
- final Map repositories
-
- final Map boms
-
- DependencyMetadata(Version bootVersion, Map dependencies,
- Map repositories, Map boms) {
- this.bootVersion = bootVersion
- this.dependencies = dependencies
- this.repositories = repositories
- this.boms = boms
- }
-
-}
diff --git a/initializr-generator/src/main/groovy/io/spring/initializr/metadata/InitializrConfiguration.groovy b/initializr-generator/src/main/groovy/io/spring/initializr/metadata/InitializrConfiguration.groovy
deleted file mode 100644
index 04bab76f..00000000
--- a/initializr-generator/src/main/groovy/io/spring/initializr/metadata/InitializrConfiguration.groovy
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
- * Copyright 2012-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.
- * You may obtain a copy of the License at
- *
- * http://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.metadata
-
-/**
- * Various configuration options used by the service.
- *
- * @author Stephane Nicoll
- */
-class InitializrConfiguration {
-
- /**
- * Environment options.
- */
- final Env env = new Env()
-
- void validate() {
- env.validate()
- }
-
- void merge(InitializrConfiguration other) {
- env.merge(other.env)
- }
-
- /**
- * Generate a suitable application name based on the specified name. If no suitable
- * application name can be generated from the specified {@code name}, the
- * {@link Env#fallbackApplicationName} is used instead.
- *
No suitable application name can be generated if the name is {@code null} or
- * if it contains an invalid character for a class identifier.
- * @see Env#fallbackApplicationName
- * @see Env#invalidApplicationNames
- */
- String generateApplicationName(String name) {
- if (!name) {
- return env.fallbackApplicationName
- }
- String text = splitCamelCase(name.trim())
- String result = text.replaceAll("(_|-| |:)+([A-Za-z0-9])", { Object[] it ->
- it[2].toUpperCase()
- })
- if (!result.endsWith('Application')) {
- result += 'Application'
- }
- String candidate = result.capitalize();
- if (hasInvalidChar(candidate) || env.invalidApplicationNames.contains(candidate)) {
- return env.fallbackApplicationName
- } else {
- return candidate
- }
- }
-
- /**
- * Clean the specified package name if necessary. If the package name cannot
- * be transformed to a valid package name, the {@code defaultPackageName}
- * is used instead.
- *
The package name cannot be cleaned if the specified {@code packageName}
- * is {@code null} or if it contains an invalid character for a class identifier.
- * @see Env#invalidPackageNames
- */
- String cleanPackageName(String packageName, String defaultPackageName) {
- if (!packageName) {
- return defaultPackageName
- }
- String candidate = packageName.trim().split('\\W+').join('.')
- if (hasInvalidChar(candidate.replace('.', '')) || env.invalidPackageNames.contains(candidate)) {
- return defaultPackageName
- } else {
- candidate
- }
- }
-
- private static String splitCamelCase(String text) {
- text.split('(? 1) {
- for (int i = 1; i < text.length(); i++) {
- if (!Character.isJavaIdentifierPart(text.charAt(i))) {
- return true
- }
- }
- }
- return false
- }
-
- /**
- * Defines additional environment settings.
- */
- static class Env {
-
- /**
- * The url of the repository servicing distribution bundle.
- */
- String artifactRepository = 'https://repo.spring.io/release/'
-
- /**
- * The metadata url of the Spring Boot project.
- */
- String springBootMetadataUrl = 'https://spring.io/project_metadata/spring-boot'
-
- /**
- * Tracking code for Google Analytics. Only enabled if a value is explicitly provided.
- */
- String googleAnalyticsTrackingCode
-
- /**
- * The application name to use if none could be generated.
- */
- String fallbackApplicationName = 'Application'
-
- /**
- * The list of invalid application names. If such name is chosen or generated,
- * the "fallbackApplicationName" should be used instead.
- */
- List invalidApplicationNames = [
- 'SpringApplication',
- 'SpringBootApplication'
- ]
-
- /**
- * The list of invalid package names. If such name is chosen or generated,
- * the the default package name should be used instead.
- */
- List invalidPackageNames = [
- 'org.springframework'
- ]
-
- /**
- * Force SSL support. When enabled, any access using http generate https links.
- */
- boolean forceSsl = true
-
- /**
- * The "BillOfMaterials" that are referenced in this instance, identified by an
- * arbitrary identifier that can be used in the dependencies definition.
- */
- final Map boms = [:]
-
- /**
- * The "Repository" instances that are referenced in this instance, identified by
- * an arbitrary identifier that can be used in the dependencies definition.
- */
- final Map repositories = [:]
-
- /**
- * Gradle-specific settings.
- */
- final Gradle gradle = new Gradle()
-
- /**
- * Kotlin-specific settings.
- */
- final Kotlin kotlin = new Kotlin()
-
- /**
- * Maven-specific settings.
- */
- final Maven maven = new Maven()
-
- Env() {
- repositories['spring-snapshots'] = new Repository(name: 'Spring Snapshots',
- url: new URL('https://repo.spring.io/snapshot'), snapshotsEnabled: true)
- repositories['spring-milestones'] = new Repository(name: 'Spring Milestones',
- url: new URL('https://repo.spring.io/milestone'), snapshotsEnabled: false)
- }
-
- void setArtifactRepository(String artifactRepository) {
- if (!artifactRepository.endsWith('/')) {
- artifactRepository = artifactRepository + '/'
- }
- this.artifactRepository = artifactRepository
- }
-
- void validate() {
- maven.parent.validate()
- boms.each {
- it.value.validate()
- }
- }
-
- void merge(Env other) {
- artifactRepository = other.artifactRepository
- springBootMetadataUrl = other.springBootMetadataUrl
- googleAnalyticsTrackingCode = other.googleAnalyticsTrackingCode
- fallbackApplicationName = other.fallbackApplicationName
- invalidApplicationNames = other.invalidApplicationNames
- forceSsl = other.forceSsl
- gradle.merge(other.gradle)
- kotlin.version = other.kotlin.version
- maven.merge(other.maven)
- other.boms.each { id, bom ->
- if (!boms[id]) {
- boms[id] = bom
- }
- }
- other.repositories.each { id, repo ->
- if (!repositories[id]) {
- repositories[id] = repo
- }
- }
- }
-
- static class Gradle {
-
- /**
- * Version of the "dependency-management-plugin" to use.
- */
- String dependencyManagementPluginVersion
-
- private void merge(Gradle other) {
- dependencyManagementPluginVersion = other.dependencyManagementPluginVersion
- }
-
- }
-
- static class Kotlin {
-
- /**
- * Kotlin version to use.
- */
- String version
- }
-
- static class Maven {
-
- /**
- * Custom parent pom to use for generated projects.
- */
- final ParentPom parent = new ParentPom()
-
- private void merge(Maven other) {
- parent.groupId = other.parent.groupId
- parent.artifactId = other.parent.artifactId
- parent.version = other.parent.version
- parent.includeSpringBootBom = other.parent.includeSpringBootBom
- }
-
- /**
- * Resolve the parent pom to use. If no custom parent pom is set,
- * the standard spring boot parent pom with the specified {@code bootVersion}
- * is used.
- */
- ParentPom resolveParentPom(String bootVersion) {
- return parent.groupId ? parent :
- new ParentPom(groupId: "org.springframework.boot",
- artifactId: "spring-boot-starter-parent", version: bootVersion)
- }
-
- static class ParentPom {
-
- /**
- * Parent pom groupId.
- */
- String groupId
-
- /**
- * Parent pom artifactId.
- */
- String artifactId
-
- /**
- * Parent pom version.
- */
- String version
-
- /**
- * Add the "spring-boot-dependencies" BOM to the project.
- */
- boolean includeSpringBootBom
-
- void validate() {
- if (!((!groupId && !artifactId && !version) ||
- (groupId && artifactId && version))) {
- throw new InvalidInitializrMetadataException("Custom maven pom " +
- "requires groupId, artifactId and version")
- }
- }
-
- }
-
- }
-
- }
-
-}
diff --git a/initializr-generator/src/main/groovy/io/spring/initializr/metadata/InitializrMetadata.groovy b/initializr-generator/src/main/groovy/io/spring/initializr/metadata/InitializrMetadata.groovy
deleted file mode 100644
index 29c0e266..00000000
--- a/initializr-generator/src/main/groovy/io/spring/initializr/metadata/InitializrMetadata.groovy
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * Copyright 2012-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.
- * You may obtain a copy of the License at
- *
- * http://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.metadata
-
-import io.spring.initializr.util.Version
-import io.spring.initializr.util.VersionParser
-
-/**
- * Meta-data used to generate a project.
- *
- * @author Stephane Nicoll
- * @see ServiceCapability
- */
-class InitializrMetadata {
-
- final InitializrConfiguration configuration
-
- final DependenciesCapability dependencies = new DependenciesCapability()
-
- final TypeCapability types = new TypeCapability()
-
- final SingleSelectCapability bootVersions =
- new SingleSelectCapability('bootVersion', 'Spring Boot Version', 'spring boot version')
-
- final SingleSelectCapability packagings =
- new SingleSelectCapability('packaging', 'Packaging', 'project packaging')
-
- final SingleSelectCapability javaVersions =
- new SingleSelectCapability('javaVersion', 'Java Version', 'language level')
-
- final SingleSelectCapability languages =
- new SingleSelectCapability('language', 'Language', 'programming language')
-
- final TextCapability name = new TextCapability('name', 'Name', 'project name (infer application name)')
-
- final TextCapability description = new TextCapability('description', 'Description', 'project description')
-
- final TextCapability groupId = new TextCapability('groupId', 'Group', 'project coordinates')
-
- final TextCapability artifactId = new ArtifactIdCapability(name)
-
- final TextCapability version = new TextCapability('version', 'Version', 'project version')
-
- final TextCapability packageName = new PackageCapability(groupId)
-
- InitializrMetadata() {
- this(new InitializrConfiguration())
- }
-
- protected InitializrMetadata(InitializrConfiguration configuration) {
- this.configuration = configuration
- }
-
- /**
- * Merge this instance with the specified argument
- * @param other
- */
- void merge(InitializrMetadata other) {
- this.configuration.merge(other.configuration)
- this.dependencies.merge(other.dependencies)
- this.types.merge(other.types)
- this.bootVersions.merge(other.bootVersions)
- this.packagings.merge(other.packagings)
- this.javaVersions.merge(other.javaVersions)
- this.languages.merge(other.languages)
- this.name.merge(other.name)
- this.description.merge(other.description)
- this.groupId.merge(other.groupId)
- this.artifactId.merge(other.artifactId)
- this.version.merge(other.version)
- this.packageName.merge(other.packageName)
- }
-
- /**
- * Validate the metadata.
- */
- void validate() {
- this.configuration.validate()
- dependencies.validate()
-
- def repositories = configuration.env.repositories
- def boms = configuration.env.boms
- for (Dependency dependency : dependencies.all) {
- if (dependency.bom && !boms[dependency.bom]) {
- throw new InvalidInitializrMetadataException("Dependency $dependency " +
- "defines an invalid BOM id $dependency.bom, available boms $boms")
- }
-
- if (dependency.repository && !repositories[dependency.repository]) {
- throw new InvalidInitializrMetadataException("Dependency $dependency " +
- "defines an invalid repository id $dependency.repository, available repositores $repositories")
- }
- }
- for (BillOfMaterials bom : boms.values()) {
- for (String r : bom.repositories) {
- if (!repositories[r]) {
- throw new InvalidInitializrMetadataException("$bom " +
- "defines an invalid repository id $r, available repositores $repositories")
- }
- }
- for (String b : bom.additionalBoms) {
- if (!boms[b]) {
- throw new InvalidInitializrMetadataException("$bom defines an invalid " +
- "additional bom id $b, available boms $boms")
- }
- }
- for (BillOfMaterials.Mapping m : bom.mappings) {
- for (String r : m.repositories) {
- if (!repositories[r]) {
- throw new InvalidInitializrMetadataException("$m of $bom " +
- "defines an invalid repository id $r, available repositores $repositories")
- }
-
- }
- for (String b : m.additionalBoms) {
- if (!boms[b]) {
- throw new InvalidInitializrMetadataException("$m of $bom defines " +
- "an invalid additional bom id $b, available boms $boms")
- }
- }
- }
- }
- }
-
- /**
- * Update the available Spring Boot versions with the specified capabilities.
- * @param versionsMetadata the Spring Boot boot versions metadata to use
- */
- void updateSpringBootVersions(List versionsMetadata) {
- bootVersions.content.clear()
- bootVersions.content.addAll(versionsMetadata)
- List bootVersions = bootVersions.content.collect {
- Version.parse(it.id)
- }
- VersionParser parser = new VersionParser(bootVersions)
- dependencies.updateVersionRange(parser)
- configuration.env.boms.values().each {
- it.updateVersionRange(parser)
- }
- }
-
- /**
- * Create an URL suitable to download Spring Boot cli for the specified version and extension.
- */
- String createCliDistributionURl(String extension) {
- String bootVersion = defaultId(bootVersions)
- configuration.env.artifactRepository + "org/springframework/boot/spring-boot-cli/" +
- "$bootVersion/spring-boot-cli-$bootVersion-bin.$extension"
- }
-
- /**
- * Create a {@link BillOfMaterials} for the spring boot BOM.
- */
- BillOfMaterials createSpringBootBom(String bootVersion, String versionProperty) {
- new BillOfMaterials(groupId: 'org.springframework.boot', artifactId: 'spring-boot-dependencies',
- version: bootVersion, versionProperty: versionProperty, order: 100)
- }
-
- /**
- * Return the defaults for the capabilities defined on this instance.
- */
- Map defaults() {
- def defaults = [:]
- defaults['type'] = defaultId(types)
- defaults['bootVersion'] = defaultId(bootVersions)
- defaults['packaging'] = defaultId(packagings)
- defaults['javaVersion'] = defaultId(javaVersions)
- defaults['language'] = defaultId(languages)
- defaults['groupId'] = groupId.content
- defaults['artifactId'] = artifactId.content
- defaults['version'] = version.content
- defaults['name'] = name.content
- defaults['description'] = description.content
- defaults['packageName'] = packageName.content
- defaults
- }
-
- private static String defaultId(def element) {
- def defaultValue = element.default
- defaultValue ? defaultValue.id : null
- }
-
- private static class ArtifactIdCapability extends TextCapability {
- private final TextCapability nameCapability
-
- ArtifactIdCapability(TextCapability nameCapability) {
- super('artifactId', 'Artifact', 'project coordinates (infer archive name)')
- this.nameCapability = nameCapability
- }
-
- @Override
- String getContent() {
- String value = super.getContent()
- value == null ? nameCapability.content : value
- }
- }
-
- private static class PackageCapability extends TextCapability {
- private final TextCapability nameCapability
-
- PackageCapability(TextCapability nameCapability) {
- super('packageName', 'Package Name', 'root package')
- this.nameCapability = nameCapability
- }
-
- @Override
- String getContent() {
- String value = super.getContent()
- value ?: (nameCapability.content != null ? nameCapability.content.replace('-', '.') : null)
- }
- }
-
-}
diff --git a/initializr-generator/src/main/groovy/io/spring/initializr/metadata/InitializrMetadataBuilder.groovy b/initializr-generator/src/main/groovy/io/spring/initializr/metadata/InitializrMetadataBuilder.groovy
deleted file mode 100644
index 8204add9..00000000
--- a/initializr-generator/src/main/groovy/io/spring/initializr/metadata/InitializrMetadataBuilder.groovy
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Copyright 2012-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.
- * You may obtain a copy of the License at
- *
- * http://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.metadata
-
-import java.nio.charset.Charset
-
-import com.fasterxml.jackson.databind.ObjectMapper
-import groovy.util.logging.Log
-
-import org.springframework.core.io.Resource
-import org.springframework.util.StreamUtils
-
-/**
- * Builder for {@link InitializrMetadata}. Allows to read metadata from any arbitrary resource,
- * including remote URLs.
- *
- * @author Stephane Nicoll
- * @see InitializrMetadataCustomizer
- */
-class InitializrMetadataBuilder {
-
- private final List customizers = []
- private final InitializrConfiguration configuration
-
- private InitializrMetadataBuilder(InitializrConfiguration configuration) {
- this.configuration = configuration
- }
-
- /**
- * Create a builder instance from the specified {@link InitializrProperties}. Initialize
- * the configuration to use.
- * @see #withInitializrProperties(InitializrProperties)
- */
- public static InitializrMetadataBuilder fromInitializrProperties(InitializrProperties configuration) {
- new InitializrMetadataBuilder(configuration).withInitializrProperties(configuration)
- }
-
- /**
- * Create an empty builder instance with a default {@link InitializrConfiguration}
- */
- public static InitializrMetadataBuilder create() {
- new InitializrMetadataBuilder(new InitializrConfiguration())
- }
-
-
- /**
- * Add a {@link InitializrProperties} to be merged with other content. Merges the settings only
- * and not the configuration.
- * @see #withInitializrProperties(InitializrProperties, boolean)
- */
- InitializrMetadataBuilder withInitializrProperties(InitializrProperties properties) {
- withInitializrProperties(properties, false)
- }
-
- /**
- * Add a {@link InitializrProperties} to be merged with other content.
- * @param properties the settings to merge onto this instance
- * @param mergeConfiguration specify if service configuration should be merged as well
- */
- InitializrMetadataBuilder withInitializrProperties(InitializrProperties properties, boolean mergeConfiguration) {
- if (mergeConfiguration) {
- this.configuration.merge(properties)
- }
- withCustomizer(new InitializerPropertiesCustomizer(properties))
- }
-
- /**
- * Add a {@link InitializrMetadata} to be merged with other content.
- * @param resource a resource to a json document describing the metadata to include
- */
- InitializrMetadataBuilder withInitializrMetadata(Resource resource) {
- withCustomizer(new ResourceInitializrMetadataCustomizer(resource))
- }
-
- /**
- * Add a {@link InitializrMetadataCustomizer}. customizers are invoked in their
- * order of addition.
- * @see InitializrMetadataCustomizer
- */
- InitializrMetadataBuilder withCustomizer(InitializrMetadataCustomizer customizer) {
- customizers << customizer
- this
- }
-
- /**
- * Build a {@link InitializrMetadata} based on the state of this builder.
- */
- InitializrMetadata build() {
- InitializrConfiguration config = this.configuration ?: new InitializrConfiguration()
- InitializrMetadata metadata = createInstance(config)
- for (InitializrMetadataCustomizer customizer : customizers) {
- customizer.customize(metadata)
- }
- applyDefaults(metadata)
- metadata.validate()
- metadata
- }
-
- /**
- * Creates an empty instance based on the specified {@link InitializrConfiguration}
- */
- protected InitializrMetadata createInstance(InitializrConfiguration configuration) {
- new InitializrMetadata(configuration)
- }
-
- /**
- * Apply defaults to capabilities that have no value.
- */
- protected applyDefaults(InitializrMetadata metadata) {
- if (!metadata.name.content) {
- metadata.name.content = 'demo'
- }
- if (!metadata.description.content) {
- metadata.description.content = 'Demo project for Spring Boot'
- }
- if (!metadata.groupId.content) {
- metadata.groupId.content = 'com.example'
- }
- if (!metadata.version.content) {
- metadata.version.content = '0.0.1-SNAPSHOT'
- }
- }
-
- private static class InitializerPropertiesCustomizer implements InitializrMetadataCustomizer {
-
- private final InitializrProperties properties
-
- InitializerPropertiesCustomizer(InitializrProperties properties) {
- this.properties = properties
- }
-
- @Override
- void customize(InitializrMetadata metadata) {
- metadata.dependencies.merge(properties.dependencies)
- metadata.types.merge(properties.types)
- metadata.bootVersions.merge(properties.bootVersions)
- metadata.packagings.merge(properties.packagings)
- metadata.javaVersions.merge(properties.javaVersions)
- metadata.languages.merge(properties.languages)
- properties.groupId.apply(metadata.groupId)
- properties.artifactId.apply(metadata.artifactId)
- properties.version.apply(metadata.version)
- properties.name.apply(metadata.name)
- properties.description.apply(metadata.description)
- properties.packageName.apply(metadata.packageName)
- }
- }
-
- @Log
- private static class ResourceInitializrMetadataCustomizer implements InitializrMetadataCustomizer {
-
- private static final Charset UTF_8 = Charset.forName('UTF-8')
-
- private final Resource resource
-
- ResourceInitializrMetadataCustomizer(Resource resource) {
- this.resource = resource
- }
-
- @Override
- void customize(InitializrMetadata metadata) {
- log.info("Loading initializr metadata from $resource")
- def content = StreamUtils.copyToString(resource.getInputStream(), UTF_8)
- ObjectMapper objectMapper = new ObjectMapper()
- def anotherMetadata = objectMapper.readValue(content, InitializrMetadata)
- metadata.merge(anotherMetadata)
- }
-
- }
-
-}
diff --git a/initializr-generator/src/main/groovy/io/spring/initializr/metadata/InitializrProperties.groovy b/initializr-generator/src/main/groovy/io/spring/initializr/metadata/InitializrProperties.groovy
deleted file mode 100644
index c52853b3..00000000
--- a/initializr-generator/src/main/groovy/io/spring/initializr/metadata/InitializrProperties.groovy
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright 2012-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.
- * You may obtain a copy of the License at
- *
- * http://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.metadata
-
-import com.fasterxml.jackson.annotation.JsonIgnore
-
-import org.springframework.boot.context.properties.ConfigurationProperties
-
-/**
- * Configuration of the initializr service.
- *
- * @author Stephane Nicoll
- */
-@ConfigurationProperties(prefix = 'initializr')
-class InitializrProperties extends InitializrConfiguration {
-
- /**
- * Dependencies, organized in groups (i.e. themes).
- */
- @JsonIgnore
- final List dependencies = []
-
- /**
- * Available project types.
- */
- @JsonIgnore
- final List types = []
-
- /**
- * Available packaging types.
- */
- @JsonIgnore
- final List packagings = []
-
- /**
- * Available java versions.
- */
- @JsonIgnore
- final List javaVersions = []
-
- /**
- * Available programming languages.
- */
- @JsonIgnore
- final List languages = []
-
- /**
- * Available Spring Boot versions.
- */
- @JsonIgnore
- final List bootVersions = []
-
- /**
- * GroupId metadata.
- */
- @JsonIgnore
- final SimpleElement groupId = new SimpleElement(value: 'com.example')
-
- /**
- * ArtifactId metadata.
- */
- @JsonIgnore
- final SimpleElement artifactId = new SimpleElement()
-
- /**
- * Version metadata.
- */
- @JsonIgnore
- final SimpleElement version = new SimpleElement(value: '0.0.1-SNAPSHOT')
-
- /**
- * Name metadata.
- */
- @JsonIgnore
- final SimpleElement name = new SimpleElement(value: 'demo')
-
- /**
- * Description metadata.
- */
- @JsonIgnore
- final SimpleElement description = new SimpleElement(value: 'Demo project for Spring Boot')
-
- /**
- * Package name metadata.
- */
- @JsonIgnore
- final SimpleElement packageName = new SimpleElement()
-
-
- static class SimpleElement {
- /**
- * Element title.
- */
- String title
-
- /**
- * Element description.
- */
- String description
-
- /**
- * Element default value.
- */
- String value
-
- void apply(TextCapability capability) {
- if (title) {
- capability.title = title
- }
- if (description) {
- capability.description = description
- }
- if (value) {
- capability.content = value
- }
- }
- }
-
-}
diff --git a/initializr-generator/src/main/groovy/io/spring/initializr/metadata/Link.groovy b/initializr-generator/src/main/groovy/io/spring/initializr/metadata/Link.groovy
deleted file mode 100644
index 95ad317a..00000000
--- a/initializr-generator/src/main/groovy/io/spring/initializr/metadata/Link.groovy
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright 2012-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.
- * You may obtain a copy of the License at
- *
- * http://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.metadata
-
-import com.fasterxml.jackson.annotation.JsonIgnore
-import com.fasterxml.jackson.annotation.JsonInclude
-import groovy.transform.ToString
-
-/**
- * Metadata for a link. Each link has a "relation" that potentially attaches a strong
- * semantic to the nature of the link. The URI of the link itself can be templated by
- * including variables in the form `{variableName}`.
- *
- * An actual {@code URI} can be generated using {@code expand}, providing a mapping for
- * those variables.
- *
- * @author Dave Syer
- * @author Stephane Nicoll
- */
-@ToString(ignoreNulls = true, includePackage = false)
-class Link {
-
- private static final String VARIABLE_REGEX = "\\{(\\w+)\\}";
-
- /**
- * The relation of the link.
- */
- String rel;
-
- /**
- * The URI the link is pointing to.
- */
- String href
-
- /**
- * Specify if the URI is templated.
- */
- @JsonInclude(JsonInclude.Include.NON_DEFAULT)
- boolean templated
-
- @JsonIgnore
- final Set templateVariables = []
-
- /**
- * A description of the link.
- */
- @JsonInclude(JsonInclude.Include.NON_NULL)
- String description
-
- Set getTemplateVariables() {
- Collections.unmodifiableSet(templateVariables)
- }
-
- void setHref(String href) {
- this.href = href
- }
-
- void resolve() {
- if (!rel) {
- throw new InvalidInitializrMetadataException(
- "Invalid link $this: rel attribute is mandatory")
- }
- if (!href) {
- throw new InvalidInitializrMetadataException(
- "Invalid link $this: href attribute is mandatory")
- }
- def matcher = (href =~ VARIABLE_REGEX)
- while (matcher.find()) {
- def variable = matcher.group(1)
- this.templateVariables << variable
- }
- this.templated = this.templateVariables
- }
-
- /**
- * Expand the link using the specified parameters.
- * @param parameters the parameters value
- * @return an URI where all variables have been expanded
- */
- URI expand(Map parameters) {
- String result = href
- templateVariables.forEach { var ->
- Object value = parameters[var]
- if (!value) {
- throw new IllegalArgumentException(
- "Could not explan $href, missing value for '$var'")
- }
- result = result.replace("{$var}", value.toString())
- }
- new URI(result)
- }
-
- public static Link create(String rel, String href) {
- return new Link(rel: rel, href: href);
- }
-
- public static Link create(String rel, String href, String description) {
- return new Link(rel: rel, href: href, description: description);
- }
-
- public static Link create(String rel, String href, boolean templated) {
- return new Link(rel: rel, href: href, templated: templated);
- }
-
-}
diff --git a/initializr-generator/src/main/groovy/io/spring/initializr/metadata/Repository.groovy b/initializr-generator/src/main/groovy/io/spring/initializr/metadata/Repository.groovy
deleted file mode 100644
index 70c83207..00000000
--- a/initializr-generator/src/main/groovy/io/spring/initializr/metadata/Repository.groovy
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright 2012-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.
- * You may obtain a copy of the License at
- *
- * http://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.metadata
-
-import groovy.transform.EqualsAndHashCode
-import groovy.transform.ToString
-
-/**
- * Define a repository to be represented in the generated project
- * if a dependency refers to it.
- *
- * @author Stephane Nicoll
- */
-@EqualsAndHashCode
-@ToString(includePackage = false)
-class Repository {
-
- String name
- URL url
- boolean snapshotsEnabled
-
-}
diff --git a/initializr-generator/src/main/groovy/io/spring/initializr/metadata/ServiceCapability.groovy b/initializr-generator/src/main/groovy/io/spring/initializr/metadata/ServiceCapability.groovy
deleted file mode 100644
index b70d6e36..00000000
--- a/initializr-generator/src/main/groovy/io/spring/initializr/metadata/ServiceCapability.groovy
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright 2012-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.
- * You may obtain a copy of the License at
- *
- * http://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.metadata
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties
-import com.fasterxml.jackson.annotation.JsonInclude
-import groovy.transform.AutoClone
-import groovy.transform.AutoCloneStyle
-
-import org.springframework.util.Assert
-
-/**
- * Defines a capability of the initializr service. Each capability
- * is defined by a id and a {@link ServiceCapabilityType type}.
- *
- * @author Stephane Nicoll
- */
-@JsonIgnoreProperties(["default", "all"])
-@JsonInclude(JsonInclude.Include.NON_NULL)
-@AutoClone(style = AutoCloneStyle.COPY_CONSTRUCTOR)
-abstract class ServiceCapability implements Cloneable {
-
- final String id
-
- final ServiceCapabilityType type
-
- /**
- * A title of the capability, used as a header text or label.
- */
- String title
-
- /**
- * A description of the capability, used in help usage or UI tooltips.
- */
- String description
-
- protected ServiceCapability(String id, ServiceCapabilityType type) {
- this.id = id
- this.type = type
- }
-
- protected ServiceCapability(String id, ServiceCapabilityType type, String title, String description) {
- this.id = id
- this.type = type
- this.title = title
- this.description = description
- }
-
- /**
- * Return the "content" of this capability. The structure of the content
- * vastly depends on the {@link ServiceCapability type} of the capability.
- */
- abstract T getContent()
-
- /**
- * Merge the content of this instance with the specified content.
- * @see #merge(io.spring.initializr.metadata.ServiceCapability)
- */
- abstract void merge(T otherContent)
-
- /**
- * Merge this capability with the specified argument. The service capabilities
- * should match (i.e have the same {@code id} and {@code type}). Sub-classes
- * may merge additional content.
- */
- void merge(ServiceCapability other) {
- Assert.notNull(other, "Other must not be null")
- Assert.state(this.id.equals(other.id))
- Assert.state(this.type.equals(other.type))
- if (other.title) {
- this.title = other.title
- }
- if (other.description) {
- this.description = other.description
- }
- merge(other.content)
- }
-
-}
-
diff --git a/initializr-generator/src/main/groovy/io/spring/initializr/metadata/SingleSelectCapability.groovy b/initializr-generator/src/main/groovy/io/spring/initializr/metadata/SingleSelectCapability.groovy
deleted file mode 100644
index 743fc6eb..00000000
--- a/initializr-generator/src/main/groovy/io/spring/initializr/metadata/SingleSelectCapability.groovy
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright 2012-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.
- * You may obtain a copy of the License at
- *
- * http://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.metadata
-
-import java.util.concurrent.CopyOnWriteArrayList
-
-import com.fasterxml.jackson.annotation.JsonCreator
-import com.fasterxml.jackson.annotation.JsonProperty
-
-/**
- * A {@link ServiceCapabilityType#SINGLE_SELECT single select} capability.
- *
- * @author Stephane Nicoll
- */
-class SingleSelectCapability extends ServiceCapability> {
-
- final List content = new CopyOnWriteArrayList()
-
- @JsonCreator
- SingleSelectCapability(@JsonProperty("id") String id) {
- this(id, null, null)
- }
-
- SingleSelectCapability(String id, String title, String description) {
- super(id, ServiceCapabilityType.SINGLE_SELECT, title, description)
- }
-
- /**
- * Return the default element of this capability.
- */
- DefaultMetadataElement getDefault() {
- return content.find { it.default }
- }
-
- /**
- * Return the element with the specified id or {@code null} if no such
- * element exists.
- */
- DefaultMetadataElement get(String id) {
- return content.find { id.equals(it.id)}
- }
-
- @Override
- void merge(List otherContent) {
- otherContent.each {
- if (!get(it.id)) {
- content << it
- }
- }
- }
-
-}
diff --git a/initializr-generator/src/main/groovy/io/spring/initializr/metadata/Type.groovy b/initializr-generator/src/main/groovy/io/spring/initializr/metadata/Type.groovy
deleted file mode 100644
index 12431b29..00000000
--- a/initializr-generator/src/main/groovy/io/spring/initializr/metadata/Type.groovy
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright 2012-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.
- * You may obtain a copy of the License at
- *
- * http://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.metadata
-
-/**
- * Defines a particular project type. Each type is associated to a concrete
- * action that should be invoked to generate the content of that type.
- *
- * @author Stephane Nicoll
- */
-class Type extends DefaultMetadataElement implements Describable {
-
- String description
-
- @Deprecated
- String stsId
-
- String action
-
- final Map tags = [:]
-
- void setAction(String action) {
- String actionToUse = action
- if (!actionToUse.startsWith("/")) {
- actionToUse = "/" + actionToUse
- }
- this.action = actionToUse
- }
-
-}
diff --git a/initializr-generator/src/main/groovy/io/spring/initializr/util/Agent.groovy b/initializr-generator/src/main/groovy/io/spring/initializr/util/Agent.groovy
deleted file mode 100644
index 9b34269b..00000000
--- a/initializr-generator/src/main/groovy/io/spring/initializr/util/Agent.groovy
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright 2012-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.
- * You may obtain a copy of the License at
- *
- * http://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.util
-
-/**
- * Defines the agent that submitted a request.
- *
- * @author Stephane Nicoll
- */
-class Agent {
-
- /**
- * The {@link AgentId}.
- */
- final AgentId id
-
- /**
- * The version of the agent, if any
- */
- final String version
-
- Agent(AgentId id, String version) {
- this.id = id
- this.version = version
- }
-
- /**
- * Create an {@link Agent} based on the specified {@code User-Agent} header.
- * @param userAgent the user agent
- * @return an {@link Agent} instance or {@code null}
- */
- static Agent fromUserAgent(String userAgent) {
- UserAgentHandler.parse(userAgent)
- }
-
- /**
- * Defines the various known agents.
- */
- static enum AgentId {
-
- CURL('curl', 'curl'),
-
- HTTPIE('httpie', 'HTTPie'),
-
- SPRING_BOOT_CLI('spring', 'SpringBootCli'),
-
- STS('sts', 'STS'),
-
- INTELLIJ_IDEA('intellijidea', 'IntelliJ IDEA'),
-
- NETBEANS('netbeans', 'NetBeans'),
-
- BROWSER('browser', 'Browser')
-
- final String id
- final String name
-
- private AgentId(String id, String name) {
- this.id = id
- this.name = name
- }
- }
-
- private static class UserAgentHandler {
-
- private static final TOOL_REGEX = '([^\\/]*)\\/([^ ]*).*'
-
- private static final STS_REGEX = 'STS (.*)'
-
- private static final NETBEANS_REGEX = 'nb-springboot-plugin\\/(.*)'
-
- static Agent parse(String userAgent) {
- def matcher = (userAgent =~ TOOL_REGEX)
- if (matcher.matches()) {
- String name = matcher.group(1)
- for (AgentId id : AgentId.values()) {
- if (name.equals(id.name)) {
- String version = matcher.group(2)
- return new Agent(id, version)
- }
- }
- }
- matcher = userAgent =~ STS_REGEX
- if (matcher.matches()) {
- return new Agent(AgentId.STS, matcher.group(1))
- }
- matcher = userAgent =~ NETBEANS_REGEX
- if (matcher.matches()) {
- return new Agent(AgentId.NETBEANS, matcher.group(1))
- }
-
- if (userAgent.equals(AgentId.INTELLIJ_IDEA.name)) {
- return new Agent(AgentId.INTELLIJ_IDEA, null)
- }
- if (userAgent.contains('Mozilla/5.0')) { // Super heuristics
- return new Agent(AgentId.BROWSER, null)
- }
- return null
- }
-
- }
-
-}
diff --git a/initializr-generator/src/main/groovy/io/spring/initializr/util/GroovyTemplate.groovy b/initializr-generator/src/main/groovy/io/spring/initializr/util/GroovyTemplate.groovy
deleted file mode 100644
index 99d47f83..00000000
--- a/initializr-generator/src/main/groovy/io/spring/initializr/util/GroovyTemplate.groovy
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright 2012-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.
- * You may obtain a copy of the License at
- *
- * http://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.util
-
-import java.util.concurrent.ConcurrentMap
-
-import groovy.text.GStringTemplateEngine
-import groovy.text.Template
-import groovy.text.TemplateEngine
-import org.codehaus.groovy.control.CompilationFailedException
-
-import org.springframework.util.ConcurrentReferenceHashMap
-
-/**
- * @author Dave Syer
- */
-class GroovyTemplate {
-
- boolean cache = true
-
- private final TemplateEngine engine
- private final ConcurrentMap templateCaches = new ConcurrentReferenceHashMap<>()
-
- GroovyTemplate(TemplateEngine engine) {
- this.engine = engine
- }
-
- GroovyTemplate() {
- this(new GStringTemplateEngine())
- }
-
- String process(String name, Map model)
- throws IOException, CompilationFailedException, ClassNotFoundException {
- def template = getTemplate(name)
- def writable = template.make(model)
- def result = new StringWriter()
- writable.writeTo(result)
- result.toString()
- }
-
- Template getTemplate(String name)
- throws CompilationFailedException, ClassNotFoundException, IOException {
- if (cache) {
- return this.templateCaches.computeIfAbsent(name, { n -> loadTemplate(n) })
- }
- return loadTemplate(name)
- }
-
- protected Template loadTemplate(String name) {
- def file = new File("templates", name)
- if (file.exists()) {
- return engine.createTemplate(file)
- }
-
- def classLoader = GroovyTemplate.class.classLoader
- def resource = classLoader.getResource("templates/" + name)
- if (resource) {
- return engine.createTemplate(resource.getText('utf-8'))
- }
-
- return engine.createTemplate(name)
- }
-
-}
diff --git a/initializr-generator/src/main/groovy/io/spring/initializr/util/Version.groovy b/initializr-generator/src/main/groovy/io/spring/initializr/util/Version.groovy
deleted file mode 100644
index dfb7b7d0..00000000
--- a/initializr-generator/src/main/groovy/io/spring/initializr/util/Version.groovy
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright 2012-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.
- * You may obtain a copy of the License at
- *
- * http://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.util
-
-import groovy.transform.EqualsAndHashCode
-import groovy.transform.ToString
-
-import org.springframework.util.Assert
-
-/**
- * Define the version number of a module. A typical version is represented
- * as {@code MAJOR.MINOR.PATCH.QUALIFIER} where the qualifier can have an
- * extra version.
- *
- * For example: {@code 1.2.0.RC1} is the first release candidate of 1.2.0
- * and {@code 1.5.0.M4} is the fourth milestone of 1.5.0. The special
- * {@code RELEASE} qualifier indicates a final release (a.k.a. GA)
- *
- * The main purpose of parsing a version is to compare it with another
- * version, see {@link Comparable}.
- *
- * @author Stephane Nicoll
- */
-@EqualsAndHashCode
-@SuppressWarnings("serial")
-final class Version implements Serializable, Comparable {
-
- private static final String VERSION_REGEX = '^(\\d+)\\.(\\d+)\\.(\\d+)(?:\\.([^0-9]+)(\\d+)?)?$'
-
- private static final VersionQualifierComparator qualifierComparator = new VersionQualifierComparator()
-
- private static final VersionParser parser = new VersionParser(Collections.EMPTY_LIST)
-
- final Integer major
- final Integer minor
- final Integer patch
- final Qualifier qualifier
-
- Version(Integer major, Integer minor, Integer patch, Qualifier qualifier) {
- this.major = major
- this.minor = minor
- this.patch = patch
- this.qualifier = qualifier
- }
-
- @Override
- String toString() {
- "${major}.${minor}.${patch}" + (qualifier?".${qualifier.qualifier}${qualifier.version?:''}" : '')
- }
-
- /**
- * Parse the string representation of a {@link Version}. Throws an
- * {@link InvalidVersionException} if the version could not be parsed.
- * @param text the version text
- * @return a Version instance for the specified version text
- * @throws InvalidVersionException if the version text could not be parsed
- * @see {@link VersionParser}
- */
- static Version parse(String text) {
- return parser.parse(text)
- }
-
- /**
- * Parse safely the specified string representation of a {@link Version}.
- *
- * Return {@code null} if the text represents an invalid version.
- * @param text the version text
- * @return a Version instance for the specified version text
- * @see {@link VersionParser}
- */
- static Version safeParse(String text) {
- try {
- return parse(text)
- } catch (InvalidVersionException e) {
- return null
- }
- }
-
- @Override
- int compareTo(Version other) {
- if (other == null) {
- return 1
- }
- int majorDiff = safeCompare(this.major, other.major)
- if (majorDiff != 0) {
- return majorDiff
- }
- int minorDiff = safeCompare(this.minor, other.minor)
- if (minorDiff != 0) {
- return minorDiff
- }
- int patch = safeCompare(this.patch, other.patch)
- if (patch != 0) {
- return patch
- }
- qualifierComparator.compare(this.qualifier, other.qualifier)
- }
-
- private static int safeCompare(Integer first, Integer second) {
- int firstIndex = first ?: 0
- int secondIndex = second ?: 0
- return firstIndex.compareTo(secondIndex)
- }
-
- @ToString
- @EqualsAndHashCode
- static class Qualifier {
- String qualifier
- Integer version
- }
-
-
- private static class VersionQualifierComparator implements Comparator {
-
- static final String RELEASE = 'RELEASE'
- static final String SNAPSHOT = 'BUILD-SNAPSHOT'
- static final String MILESTONE = 'M'
- static final String RC = 'RC'
-
- static final List KNOWN_QUALIFIERS = Arrays.asList(MILESTONE, RC, SNAPSHOT, RELEASE)
-
- @Override
- int compare(Qualifier o1, Qualifier o2) {
- Qualifier first = o1 ?: new Qualifier(qualifier: RELEASE)
- Qualifier second = o2 ?: new Qualifier(qualifier: RELEASE)
-
- int qualifier = compareQualifier(first, second)
- qualifier ? qualifier : compareQualifierVersion(first, second)
- }
-
- private static int compareQualifierVersion(Qualifier first, Qualifier second) {
- int firstVersion = first.getVersion() ?: 0
- int secondVersion = second.getVersion() ?: 0
- firstVersion.compareTo(secondVersion)
- }
-
- private static int compareQualifier(Qualifier first, Qualifier second) {
- int firstIndex = getQualifierIndex(first.qualifier)
- int secondIndex = getQualifierIndex(second.qualifier)
-
- if (firstIndex == -1 && secondIndex == -1) { // Unknown qualifier, alphabetic ordering
- return first.qualifier.compareTo(second.qualifier)
- } else {
- return firstIndex.compareTo(secondIndex)
- }
- }
-
- private static int getQualifierIndex(String qualifier) {
- qualifier ? KNOWN_QUALIFIERS.indexOf(qualifier) : RELEASE
- }
- }
-
-}
diff --git a/initializr-generator/src/main/groovy/io/spring/initializr/util/VersionRange.groovy b/initializr-generator/src/main/groovy/io/spring/initializr/util/VersionRange.groovy
deleted file mode 100644
index bfc0e5ae..00000000
--- a/initializr-generator/src/main/groovy/io/spring/initializr/util/VersionRange.groovy
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright 2012-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.
- * You may obtain a copy of the License at
- *
- * http://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.util
-
-import groovy.transform.EqualsAndHashCode
-
-import org.springframework.util.Assert
-
-/**
- * Define a {@link Version} range. A square bracket "[" or "]" denotes an inclusive
- * end of the range and a round bracket "(" or ")" denotes an exclusive end of the
- * range. A range can also be unbounded by defining a a single {@link Version}. The
- * examples below make this clear.
- *
- *
- *
"[1.2.0.RELEASE,1.3.0.RELEASE)" version 1.2.0 and any version after
- * this, up to, but not including, version 1.3.0.
- *
"(2.0.0.RELEASE,3.2.0.RELEASE]" any version after 2.0.0 up to and
- * including version 3.2.0.
- *
"1.4.5.RELEASE", version 1.4.5 and all later versions.
- *
- *
- * @author Stephane Nicoll
- */
-@EqualsAndHashCode
-class VersionRange {
-
- final Version lowerVersion
- final boolean lowerInclusive
- final Version higherVersion
- final boolean higherInclusive
-
- protected VersionRange(Version lowerVersion, boolean lowerInclusive,
- Version higherVersion, boolean higherInclusive) {
- this.lowerVersion = lowerVersion
- this.lowerInclusive = lowerInclusive
- this.higherVersion = higherVersion
- this.higherInclusive = higherInclusive
- }
-
- /**
- * Specify if the {@link Version} matches this range. Returns {@code true}
- * if the version is contained within this range, {@code false} otherwise.
- */
- boolean match(Version version) {
- Assert.notNull(version, "Version must not be null")
- def lower = lowerVersion.compareTo(version)
- if (lower > 0) {
- return false;
- } else if (!lowerInclusive && lower == 0) {
- return false;
- }
- if (higherVersion) {
- def higher = higherVersion.compareTo(version)
- if (higher < 0) {
- return false
- } else if (!higherInclusive && higher == 0) {
- return false
- }
- }
- return true
- }
-
- @Override
- String toString() {
- StringBuffer sb = new StringBuffer()
- if (lowerVersion) {
- sb.append("${lowerInclusive ? '>=' : '>'}${lowerVersion}")
- }
- if (higherVersion) {
- sb.append(" and ${higherInclusive ? '<=' : '<'}${higherVersion}")
- }
- return sb.toString()
- }
-
-}
diff --git a/initializr-generator/src/main/groovy/io/spring/initializr/metadata/InvalidInitializrMetadataException.groovy b/initializr-generator/src/main/java/io/spring/initializr/InitializrException.java
similarity index 68%
rename from initializr-generator/src/main/groovy/io/spring/initializr/metadata/InvalidInitializrMetadataException.groovy
rename to initializr-generator/src/main/java/io/spring/initializr/InitializrException.java
index 942d03b4..82b6087e 100644
--- a/initializr-generator/src/main/groovy/io/spring/initializr/metadata/InvalidInitializrMetadataException.groovy
+++ b/initializr-generator/src/main/java/io/spring/initializr/InitializrException.java
@@ -14,17 +14,21 @@
* limitations under the License.
*/
-package io.spring.initializr.metadata
-
-import groovy.transform.InheritConstructors
-import io.spring.initializr.InitializrException
+package io.spring.initializr;
/**
- * Thrown when the configuration defines invalid metadata.
+ * Base Initializr exception.
*
* @author Stephane Nicoll
*/
-@InheritConstructors
-class InvalidInitializrMetadataException extends InitializrException {
-}
+@SuppressWarnings("serial")
+public class InitializrException extends RuntimeException {
+ public InitializrException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public InitializrException(String message) {
+ super(message);
+ }
+}
diff --git a/initializr-generator/src/main/java/io/spring/initializr/generator/BasicProjectRequest.java b/initializr-generator/src/main/java/io/spring/initializr/generator/BasicProjectRequest.java
new file mode 100644
index 00000000..fea2da59
--- /dev/null
+++ b/initializr-generator/src/main/java/io/spring/initializr/generator/BasicProjectRequest.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright 2012-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.
+ * You may obtain a copy of the License at
+ *
+ * http://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;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * The base settings of a project request. Only these can be bound by user's
+ * input.
+ *
+ * @author Stephane Nicoll
+ */
+public class BasicProjectRequest {
+
+ private List style = new ArrayList<>();
+ private List dependencies = new ArrayList<>();
+ private String name;
+ private String type;
+ private String description;
+ private String groupId;
+ private String artifactId;
+ private String version;
+ private String bootVersion;
+ private String packaging;
+ private String applicationName;
+ private String language;
+ private String packageName;
+ private String javaVersion;
+
+ // The base directory to create in the archive - no baseDir by default
+ private String baseDir;
+
+ public List getStyle() {
+ return style;
+ }
+
+ public void setStyle(List style) {
+ this.style = style;
+ }
+
+ public List getDependencies() {
+ return dependencies;
+ }
+
+ public void setDependencies(List dependencies) {
+ this.dependencies = dependencies;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public String getGroupId() {
+ return groupId;
+ }
+
+ public void setGroupId(String groupId) {
+ this.groupId = groupId;
+ }
+
+ public String getArtifactId() {
+ return artifactId;
+ }
+
+ public void setArtifactId(String artifactId) {
+ this.artifactId = artifactId;
+ }
+
+ public String getVersion() {
+ return version;
+ }
+
+ public void setVersion(String version) {
+ this.version = version;
+ }
+
+ public String getBootVersion() {
+ return bootVersion;
+ }
+
+ public void setBootVersion(String bootVersion) {
+ this.bootVersion = bootVersion;
+ }
+
+ public String getPackaging() {
+ return packaging;
+ }
+
+ public void setPackaging(String packaging) {
+ this.packaging = packaging;
+ }
+
+ public String getApplicationName() {
+ return applicationName;
+ }
+
+ public void setApplicationName(String applicationName) {
+ this.applicationName = applicationName;
+ }
+
+ public String getLanguage() {
+ return language;
+ }
+
+ public void setLanguage(String language) {
+ this.language = language;
+ }
+
+ public String getPackageName() {
+ return packageName;
+ }
+
+ public void setPackageName(String packageName) {
+ this.packageName = packageName;
+ }
+
+ public String getJavaVersion() {
+ return javaVersion;
+ }
+
+ public void setJavaVersion(String javaVersion) {
+ this.javaVersion = javaVersion;
+ }
+
+ public String getBaseDir() {
+ return baseDir;
+ }
+
+ public void setBaseDir(String baseDir) {
+ this.baseDir = baseDir;
+ }
+
+}
diff --git a/initializr-generator/src/main/groovy/io/spring/initializr/generator/BuildProperties.groovy b/initializr-generator/src/main/java/io/spring/initializr/generator/BuildProperties.java
similarity index 62%
rename from initializr-generator/src/main/groovy/io/spring/initializr/generator/BuildProperties.groovy
rename to initializr-generator/src/main/java/io/spring/initializr/generator/BuildProperties.java
index 2d63b8af..47c6f912 100644
--- a/initializr-generator/src/main/groovy/io/spring/initializr/generator/BuildProperties.groovy
+++ b/initializr-generator/src/main/java/io/spring/initializr/generator/BuildProperties.java
@@ -14,29 +14,44 @@
* limitations under the License.
*/
-package io.spring.initializr.generator
+package io.spring.initializr.generator;
+
+import java.util.TreeMap;
+import java.util.function.Supplier;
/**
* Build properties associated to a project request.
*
* @author Stephane Nicoll
*/
-class BuildProperties {
+public class BuildProperties {
/**
* Maven-specific build properties, added to the regular {@code properties} element.
*/
- final TreeMap> maven = new TreeMap<>()
+ private final TreeMap> maven = new TreeMap<>();
/**
* Gradle-specific build properties, added to the {@code buildscript} section
* of the gradle build.
*/
- final TreeMap> gradle = new TreeMap<>()
+ private final TreeMap> gradle = new TreeMap<>();
/**
* Version properties. Shared between the two build systems.
*/
- final TreeMap> versions = new TreeMap<>()
+ private final TreeMap> versions = new TreeMap<>();
+
+ public TreeMap> getMaven() {
+ return maven;
+ }
+
+ public TreeMap> getGradle() {
+ return gradle;
+ }
+
+ public TreeMap> getVersions() {
+ return versions;
+ }
}
diff --git a/initializr-generator/src/main/java/io/spring/initializr/generator/CommandLineHelpGenerator.java b/initializr-generator/src/main/java/io/spring/initializr/generator/CommandLineHelpGenerator.java
new file mode 100644
index 00000000..bff98221
--- /dev/null
+++ b/initializr-generator/src/main/java/io/spring/initializr/generator/CommandLineHelpGenerator.java
@@ -0,0 +1,307 @@
+/*
+ * Copyright 2012-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.
+ * You may obtain a copy of the License at
+ *
+ * http://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;
+
+import java.beans.PropertyDescriptor;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import org.springframework.beans.BeanWrapperImpl;
+
+import io.spring.initializr.metadata.Dependency;
+import io.spring.initializr.metadata.InitializrMetadata;
+import io.spring.initializr.metadata.Type;
+import io.spring.initializr.util.GroovyTemplate;
+
+/**
+ * Generate help pages for command-line clients.
+ *
+ * @author Stephane Nicoll
+ */
+public class CommandLineHelpGenerator {
+
+ private static final String logo = " . ____ _ __ _ _\n"
+ + " /\\\\ / ___'_ __ _ _(_)_ __ __ _ \\ \\ \\ \\\n"
+ + "( ( )\\___ | '_ | '_| | '_ \\/ _` | \\ \\ \\ \\\n"
+ + " \\\\/ ___)| |_)| | | | | || (_| | ) ) ) )\n"
+ + " ' |____| .__|_| |_|_| |_\\__, | / / / /\n"
+ + " =========|_|==============|___/=/_/_/_/";
+
+ private final GroovyTemplate template;
+
+ public CommandLineHelpGenerator(GroovyTemplate template) {
+ this.template = template;
+ }
+
+ /**
+ * Generate the capabilities of the service as a generic plain text document. Used
+ * when no particular agent was detected.
+ */
+ public String generateGenericCapabilities(InitializrMetadata metadata,
+ String serviceUrl) {
+ Map model = initializeCommandLineModel(metadata, serviceUrl);
+ model.put("hasExamples", false);
+ return template.process("cli-capabilities.txt", model);
+ }
+
+ /**
+ * Generate the capabilities of the service using "curl" as a plain text document.
+ */
+ public String generateCurlCapabilities(InitializrMetadata metadata,
+ String serviceUrl) {
+ Map model = initializeCommandLineModel(metadata, serviceUrl);
+ model.put("examples", template.process("curl-examples.txt", model));
+ model.put("hasExamples", true);
+ return template.process("cli-capabilities.txt", model);
+ }
+
+ /**
+ * Generate the capabilities of the service using "HTTPie" as a plain text document.
+ */
+ public String generateHttpieCapabilities(InitializrMetadata metadata,
+ String serviceUrl) {
+ Map model = initializeCommandLineModel(metadata, serviceUrl);
+ model.put("examples", template.process("httpie-examples.txt", model));
+ model.put("hasExamples", true);
+ return template.process("cli-capabilities.txt", model);
+ }
+
+ /**
+ * Generate the capabilities of the service using Spring Boot CLI as a plain text
+ * document.
+ */
+ public String generateSpringBootCliCapabilities(InitializrMetadata metadata,
+ String serviceUrl) {
+ Map model = initializeSpringBootCliModel(metadata, serviceUrl);
+ model.put("hasExamples", false);
+ return template.process("boot-cli-capabilities.txt", model);
+ }
+
+ protected Map initializeCommandLineModel(InitializrMetadata metadata,
+ String serviceUrl) {
+ Map model = new LinkedHashMap<>();
+ model.put("logo", logo);
+ model.put("serviceUrl", serviceUrl);
+ model.put("dependencies", generateDependencyTable(metadata));
+ model.put("types", generateTypeTable(metadata, "Rel", false));
+
+ Map defaults = metadata.defaults();
+ defaults.put("applicationName", metadata.getConfiguration()
+ .generateApplicationName(metadata.getName().getContent()));
+ defaults.put("baseDir", "no base dir");
+ defaults.put("dependencies", "none");
+
+ Map parametersDescription = buildParametersDescription(metadata);
+ String[][] parameterTable = new String[defaults.size() + 1][];
+ parameterTable[0] = new String[] { "Parameter", "Description", "Default value" };
+ int i = 1;
+ for (String id : defaults.keySet().stream().sorted()
+ .collect(Collectors.toList())) {
+ String[] data = new String[3];
+ data[0] = id;
+ data[1] = (String) parametersDescription.get(id);
+ data[2] = (String) defaults.get(id);
+ parameterTable[i++] = data;
+ }
+ model.put("parameters", TableGenerator.generate(parameterTable));
+
+ return model;
+ }
+
+ protected Map initializeSpringBootCliModel(
+ InitializrMetadata metadata, String serviceUrl) {
+ Map model = new LinkedHashMap<>();
+ model.put("logo", logo);
+ model.put("serviceUrl", serviceUrl);
+ model.put("dependencies", generateDependencyTable(metadata));
+ model.put("types", generateTypeTable(metadata, "Id", true));
+
+ Map defaults = metadata.defaults();
+ Map parametersDescription = buildParametersDescription(metadata);
+ String[][] parameterTable = new String[defaults.size() + 1][];
+ parameterTable[0] = new String[] { "Id", "Description", "Default value" };
+ int i = 1;
+ for (String id : defaults.keySet().stream().sorted()
+ .collect(Collectors.toList())) {
+ String[] data = new String[3];
+ data[0] = id;
+ data[1] = (String) parametersDescription.get(id);
+ data[2] = (String) defaults.get(id);
+ parameterTable[i++] = data;
+ }
+ model.put("parameters", TableGenerator.generate(parameterTable));
+ return model;
+ }
+
+ protected String generateDependencyTable(InitializrMetadata metadata) {
+ String[][] dependencyTable = new String[metadata.getDependencies().getAll().size()
+ + 1][];
+ dependencyTable[0] = new String[] { "Id", "Description", "Required version" };
+ int i = 1;
+ for (Dependency dep : metadata.getDependencies().getAll().stream()
+ .sorted((a, b) -> a.getId().compareTo(b.getId()))
+ .collect(Collectors.toList())) {
+ String[] data = new String[3];
+ data[0] = dep.getId();
+ data[1] = dep.getDescription() != null ? dep.getDescription() : dep.getName();
+ data[2] = dep.getVersionRequirement();
+ dependencyTable[i++] = data;
+ }
+ ;
+ return TableGenerator.generate(dependencyTable);
+ }
+
+ protected String generateTypeTable(InitializrMetadata metadata, String linkHeader,
+ boolean addTags) {
+ String[][] typeTable = new String[metadata.getTypes().getContent().size() + 1][];
+ if (addTags) {
+ typeTable[0] = new String[] { linkHeader, "Description", "Tags" };
+ }
+ else {
+ typeTable[0] = new String[] { linkHeader, "Description" };
+ }
+ int i = 1;
+ for (Type type : metadata.getTypes().getContent().stream()
+ .sorted((a, b) -> a.getId().compareTo(b.getId()))
+ .collect(Collectors.toList())) {
+ String[] data = new String[typeTable[0].length];
+ data[0] = (type.isDefault() ? type.getId() + " *" : type.getId());
+ data[1] = type.getDescription() != null ? type.getDescription()
+ : type.getName();
+ if (addTags) {
+ data[2] = buildTagRepresentation(type);
+ }
+ typeTable[i++] = data;
+ }
+ return TableGenerator.generate(typeTable);
+ }
+
+ protected Map buildParametersDescription(
+ InitializrMetadata metadata) {
+ Map result = new LinkedHashMap<>();
+ BeanWrapperImpl wrapper = new BeanWrapperImpl(metadata);
+ for (PropertyDescriptor descriptor : wrapper.getPropertyDescriptors()) {
+ Object value = wrapper.getPropertyValue(descriptor.getName());
+ BeanWrapperImpl nested = new BeanWrapperImpl(value);
+ if (nested.isReadableProperty("description")
+ && nested.isReadableProperty("id")) {
+ result.put((String) nested.getPropertyValue("id"),
+ nested.getPropertyValue("description"));
+ }
+ }
+ result.put("applicationName", "application name");
+ result.put("baseDir", "base directory to create in the archive");
+ return result;
+ }
+
+ private static String buildTagRepresentation(Type type) {
+ if (type.getTags().isEmpty()) {
+ return "";
+ }
+ return String.join(",",
+ type.getTags().entrySet().stream()
+ .map(entry -> entry.getKey() + ":" + entry.getValue())
+ .collect(Collectors.toList()).toArray(new String[0]));
+ }
+
+ private static class TableGenerator {
+
+ static final String NEW_LINE = System.getProperty("line.separator");
+
+ /**
+ * Generate a table description for the specified {@code content}.
+ *
+ * The {@code content} is a two-dimensional array holding the rows of the table.
+ * The first entry holds the header of the table.
+ */
+ public static String generate(String[][] content) {
+ StringBuilder sb = new StringBuilder();
+ int[] columnsLength = computeColumnsLength(content);
+ appendTableSeparation(sb, columnsLength);
+ appendRow(sb, content, columnsLength, 0); // Headers
+ appendTableSeparation(sb, columnsLength);
+ for (int i = 1; i < content.length; i++) {
+ appendRow(sb, content, columnsLength, i);
+ }
+ appendTableSeparation(sb, columnsLength);
+ return sb.toString();
+ }
+
+ private static void appendRow(StringBuilder sb, String[][] content,
+ int[] columnsLength, int rowIndex) {
+ String[] row = content[rowIndex];
+ if (row != null) {
+ for (int i = 0; i < row.length; i++) {
+ sb.append("| ").append(fill(row[i], columnsLength[i])).append(" ");
+ }
+ }
+ sb.append("|");
+ sb.append(NEW_LINE);
+ }
+
+ private static void appendTableSeparation(StringBuilder sb, int[] headersLength) {
+ for (int headerLength : headersLength) {
+ sb.append("+").append(multiply("-", headerLength + 2));
+ }
+ sb.append("+");
+ sb.append(NEW_LINE);
+ }
+
+ private static String fill(String data, int columnSize) {
+ if (data == null) {
+ return multiply(" ", columnSize);
+ }
+ else {
+ int i = columnSize - data.length();
+ return data + multiply(" ", i);
+ }
+ }
+
+ private static String multiply(String value, int size) {
+ StringBuilder s = new StringBuilder();
+ for (int i = 0; i < size; i++) {
+ s.append(value);
+ }
+ return s.toString();
+ }
+
+ private static int[] computeColumnsLength(String[][] content) {
+ int count = content[0].length;
+ int[] result = new int[count];
+ for (int i = 0; i < count; i++) {
+ result[i] = largest(content, i);
+ }
+ return result;
+ }
+
+ private static int largest(String[][] content, int column) {
+ int max = 0;
+ for (String[] rows : content) {
+ if (rows != null) {
+ String s = rows[column];
+ if (s != null && s.length() > max) {
+ max = s.length();
+ }
+ }
+ }
+ return max;
+ }
+
+ }
+
+}
diff --git a/initializr-generator/src/main/groovy/io/spring/initializr/generator/InvalidProjectRequestException.groovy b/initializr-generator/src/main/java/io/spring/initializr/generator/InvalidProjectRequestException.java
similarity index 65%
rename from initializr-generator/src/main/groovy/io/spring/initializr/generator/InvalidProjectRequestException.groovy
rename to initializr-generator/src/main/java/io/spring/initializr/generator/InvalidProjectRequestException.java
index 2669a383..a0d0c14c 100644
--- a/initializr-generator/src/main/groovy/io/spring/initializr/generator/InvalidProjectRequestException.groovy
+++ b/initializr-generator/src/main/java/io/spring/initializr/generator/InvalidProjectRequestException.java
@@ -14,16 +14,23 @@
* limitations under the License.
*/
-package io.spring.initializr.generator
+package io.spring.initializr.generator;
-import groovy.transform.InheritConstructors
-import io.spring.initializr.InitializrException
+import io.spring.initializr.InitializrException;
/**
* Thrown when a {@link ProjectRequest} is invalid.
*
* @author Stephane Nicoll
*/
-@InheritConstructors
-class InvalidProjectRequestException extends InitializrException {
+@SuppressWarnings("serial")
+public class InvalidProjectRequestException extends InitializrException {
+
+ public InvalidProjectRequestException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public InvalidProjectRequestException(String message) {
+ super(message);
+ }
}
diff --git a/initializr-generator/src/main/groovy/io/spring/initializr/generator/ProjectFailedEvent.groovy b/initializr-generator/src/main/java/io/spring/initializr/generator/ProjectFailedEvent.java
similarity index 72%
rename from initializr-generator/src/main/groovy/io/spring/initializr/generator/ProjectFailedEvent.groovy
rename to initializr-generator/src/main/java/io/spring/initializr/generator/ProjectFailedEvent.java
index 7eb19270..a23ea2b6 100644
--- a/initializr-generator/src/main/groovy/io/spring/initializr/generator/ProjectFailedEvent.groovy
+++ b/initializr-generator/src/main/java/io/spring/initializr/generator/ProjectFailedEvent.java
@@ -14,23 +14,27 @@
* limitations under the License.
*/
-package io.spring.initializr.generator
+package io.spring.initializr.generator;
/**
* Event published when an error occured trying to generate a project.
*
* @author Stephane Nicoll
*/
-class ProjectFailedEvent extends ProjectRequestEvent {
+public class ProjectFailedEvent extends ProjectRequestEvent {
/**
* The cause of the failure.
*/
- final Exception cause
+ final Exception cause;
- ProjectFailedEvent(ProjectRequest projectRequest, Exception cause) {
- super(projectRequest)
- this.cause = cause
+ public ProjectFailedEvent(ProjectRequest projectRequest, Exception cause) {
+ super(projectRequest);
+ this.cause = cause;
+ }
+
+ public Exception getCause() {
+ return cause;
}
}
diff --git a/initializr-generator/src/main/groovy/io/spring/initializr/generator/ProjectGeneratedEvent.groovy b/initializr-generator/src/main/java/io/spring/initializr/generator/ProjectGeneratedEvent.java
similarity index 79%
rename from initializr-generator/src/main/groovy/io/spring/initializr/generator/ProjectGeneratedEvent.groovy
rename to initializr-generator/src/main/java/io/spring/initializr/generator/ProjectGeneratedEvent.java
index c9129c96..1d8f36a8 100644
--- a/initializr-generator/src/main/groovy/io/spring/initializr/generator/ProjectGeneratedEvent.groovy
+++ b/initializr-generator/src/main/java/io/spring/initializr/generator/ProjectGeneratedEvent.java
@@ -14,17 +14,17 @@
* limitations under the License.
*/
-package io.spring.initializr.generator
+package io.spring.initializr.generator;
/**
* Event published when a new project has been generated successfully.
*
* @author Stephane Nicoll
*/
-class ProjectGeneratedEvent extends ProjectRequestEvent {
+public class ProjectGeneratedEvent extends ProjectRequestEvent {
- ProjectGeneratedEvent(ProjectRequest projectRequest) {
- super(projectRequest)
+ public ProjectGeneratedEvent(ProjectRequest projectRequest) {
+ super(projectRequest);
}
}
diff --git a/initializr-generator/src/main/java/io/spring/initializr/generator/ProjectGenerator.java b/initializr-generator/src/main/java/io/spring/initializr/generator/ProjectGenerator.java
new file mode 100644
index 00000000..93df1c9b
--- /dev/null
+++ b/initializr-generator/src/main/java/io/spring/initializr/generator/ProjectGenerator.java
@@ -0,0 +1,563 @@
+/*
+ * Copyright 2012-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.
+ * You may obtain a copy of the License at
+ *
+ * http://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;
+
+import java.beans.PropertyDescriptor;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.BeanWrapperImpl;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.ApplicationEventPublisher;
+import org.springframework.util.Assert;
+import org.springframework.util.FileSystemUtils;
+import org.springframework.util.StreamUtils;
+
+import io.spring.initializr.InitializrException;
+import io.spring.initializr.metadata.Dependency;
+import io.spring.initializr.metadata.InitializrConfiguration.Env.Maven.ParentPom;
+import io.spring.initializr.metadata.InitializrMetadata;
+import io.spring.initializr.metadata.InitializrMetadataProvider;
+import io.spring.initializr.util.GroovyTemplate;
+import io.spring.initializr.util.Version;
+
+/**
+ * Generate a project based on the configured metadata.
+ *
+ * @author Dave Syer
+ * @author Stephane Nicoll
+ * @author Sebastien Deleuze
+ */
+public class ProjectGenerator {
+
+ private static final Logger log = LoggerFactory.getLogger(ProjectGenerator.class);
+
+ private static final Version VERSION_1_2_0_RC1 = Version.parse("1.2.0.RC1");
+
+ private static final Version VERSION_1_3_0_M1 = Version.parse("1.3.0.M1");
+
+ private static final Version VERSION_1_4_0_M2 = Version.parse("1.4.0.M2");
+
+ private static final Version VERSION_1_4_0_M3 = Version.parse("1.4.0.M3");
+
+ private static final Version VERSION_1_4_2_M1 = Version.parse("1.4.2.M1");
+
+ private static final Version VERSION_2_0_0_M1 = Version.parse("2.0.0.M1");
+
+ @Autowired
+ private ApplicationEventPublisher eventPublisher;
+
+ @Autowired
+ private InitializrMetadataProvider metadataProvider;
+
+ @Autowired
+ private ProjectRequestResolver requestResolver;
+
+ @Autowired
+ private GroovyTemplate groovyTemplate = new GroovyTemplate();
+
+ @Autowired
+ private ProjectResourceLocator projectResourceLocator = new ProjectResourceLocator();
+
+ @Value("${TMPDIR:.}/initializr")
+ private String tmpdir;
+
+ private File temporaryDirectory;
+ private transient Map> temporaryFiles = new LinkedHashMap<>();
+
+ public InitializrMetadataProvider getMetadataProvider() {
+ return metadataProvider;
+ }
+
+ public void setEventPublisher(ApplicationEventPublisher eventPublisher) {
+ this.eventPublisher = eventPublisher;
+ }
+
+ public void setMetadataProvider(InitializrMetadataProvider metadataProvider) {
+ this.metadataProvider = metadataProvider;
+ }
+
+ public void setRequestResolver(ProjectRequestResolver requestResolver) {
+ this.requestResolver = requestResolver;
+ }
+
+ public void setGroovyTemplate(GroovyTemplate groovyTemplate) {
+ this.groovyTemplate = groovyTemplate;
+ }
+
+ public void setProjectResourceLocator(ProjectResourceLocator projectResourceLocator) {
+ this.projectResourceLocator = projectResourceLocator;
+ }
+
+ public void setTmpdir(String tmpdir) {
+ this.tmpdir = tmpdir;
+ }
+
+ public void setTemporaryDirectory(File temporaryDirectory) {
+ this.temporaryDirectory = temporaryDirectory;
+ }
+
+ public void setTemporaryFiles(Map> temporaryFiles) {
+ this.temporaryFiles = temporaryFiles;
+ }
+
+ /**
+ * Generate a Maven pom for the specified {@link ProjectRequest}.
+ */
+ public byte[] generateMavenPom(ProjectRequest request) {
+ try {
+ Map model = resolveModel(request);
+ if (!isMavenBuild(request)) {
+ throw new InvalidProjectRequestException("Could not generate Maven pom, "
+ + "invalid project type " + request.getType());
+ }
+ byte[] content = doGenerateMavenPom(model);
+ publishProjectGeneratedEvent(request);
+ return content;
+ }
+ catch (InitializrException ex) {
+ publishProjectFailedEvent(request, ex);
+ throw ex;
+ }
+ }
+
+ /**
+ * Generate a Gradle build file for the specified {@link ProjectRequest}.
+ */
+ public byte[] generateGradleBuild(ProjectRequest request) {
+ try {
+ Map model = resolveModel(request);
+ if (!isGradleBuild(request)) {
+ throw new InvalidProjectRequestException(
+ "Could not generate Gradle build, " + "invalid project type "
+ + request.getType());
+ }
+ byte[] content = doGenerateGradleBuild(model);
+ publishProjectGeneratedEvent(request);
+ return content;
+ }
+ catch (InitializrException ex) {
+ publishProjectFailedEvent(request, ex);
+ throw ex;
+ }
+ }
+
+ /**
+ * Generate a project structure for the specified {@link ProjectRequest}. Returns a
+ * directory containing the project.
+ */
+ public File generateProjectStructure(ProjectRequest request) {
+ try {
+ return doGenerateProjectStructure(request);
+ }
+ catch (InitializrException ex) {
+ publishProjectFailedEvent(request, ex);
+ throw ex;
+ }
+ }
+
+ protected File doGenerateProjectStructure(ProjectRequest request) {
+ Map model = resolveModel(request);
+
+ File rootDir;
+ try {
+ rootDir = File.createTempFile("tmp", "", getTemporaryDirectory());
+ }
+ catch (IOException e) {
+ throw new IllegalStateException("Cannot create temp dir", e);
+ }
+ addTempFile(rootDir.getName(), rootDir);
+ rootDir.delete();
+ rootDir.mkdirs();
+
+ File dir = initializerProjectDir(rootDir, request);
+
+ if (isGradleBuild(request)) {
+ String gradle = new String(doGenerateGradleBuild(model));
+ writeText(new File(dir, "build.gradle"), gradle);
+ writeGradleWrapper(dir, Version.safeParse(request.getBootVersion()));
+ }
+ else {
+ String pom = new String(doGenerateMavenPom(model));
+ writeText(new File(dir, "pom.xml"), pom);
+ writeMavenWrapper(dir);
+ }
+
+ generateGitIgnore(dir, request);
+
+ String applicationName = request.getApplicationName();
+ String language = request.getLanguage();
+
+ String codeLocation = language;
+ File src = new File(new File(dir, "src/main/" + codeLocation),
+ request.getPackageName().replace(".", "/"));
+ src.mkdirs();
+ String extension = (language.equals("kotlin") ? "kt" : language);
+ write(new File(src, applicationName + "." + extension),
+ "Application." + extension, model);
+
+ if ("war".equals(request.getPackaging())) {
+ String fileName = "ServletInitializer." + extension;
+ write(new File(src, fileName), fileName, model);
+ }
+
+ File test = new File(new File(dir, "src/test/" + codeLocation),
+ request.getPackageName().replace(".", "/"));
+ test.mkdirs();
+ setupTestModel(request, model);
+ write(new File(test, applicationName + "Tests." + extension),
+ "ApplicationTests." + extension, model);
+
+ File resources = new File(dir, "src/main/resources");
+ resources.mkdirs();
+ writeText(new File(resources, "application.properties"), "");
+
+ if (request.hasWebFacet()) {
+ new File(dir, "src/main/resources/templates").mkdirs();
+ new File(dir, "src/main/resources/static").mkdirs();
+ }
+ publishProjectGeneratedEvent(request);
+ return rootDir;
+
+ }
+
+ /**
+ * Create a distribution file for the specified project structure directory and
+ * extension
+ */
+ public File createDistributionFile(File dir, String extension) {
+ File download = new File(getTemporaryDirectory(), dir.getName() + extension);
+ addTempFile(dir.getName(), download);
+ return download;
+ }
+
+ private File getTemporaryDirectory() {
+ if (temporaryDirectory == null) {
+ temporaryDirectory = new File(tmpdir, "initializr");
+ temporaryDirectory.mkdirs();
+ }
+ return temporaryDirectory;
+ }
+
+ /**
+ * Clean all the temporary files that are related to this root directory.
+ * @see #createDistributionFile
+ */
+ public void cleanTempFiles(File dir) {
+ List tempFiles = temporaryFiles.remove(dir.getName());
+ if (!tempFiles.isEmpty()) {
+ tempFiles.forEach((File file) -> {
+ if (file.isDirectory()) {
+ FileSystemUtils.deleteRecursively(file);
+ }
+ else if (file.exists()) {
+ file.delete();
+ }
+ });
+ }
+ }
+
+ private void publishProjectGeneratedEvent(ProjectRequest request) {
+ ProjectGeneratedEvent event = new ProjectGeneratedEvent(request);
+ eventPublisher.publishEvent(event);
+ }
+
+ private void publishProjectFailedEvent(ProjectRequest request, Exception cause) {
+ ProjectFailedEvent event = new ProjectFailedEvent(request, cause);
+ eventPublisher.publishEvent(event);
+ }
+
+ /**
+ * Generate a {@code .gitignore} file for the specified {@link ProjectRequest}
+ * @param dir the root directory of the project
+ * @param request the request to handle
+ */
+ protected void generateGitIgnore(File dir, ProjectRequest request) {
+ Map model = new LinkedHashMap<>();
+ model.put("build", isGradleBuild(request) ? "gradle" : "maven");
+ write(new File(dir, ".gitignore"), "gitignore.tmpl", model);
+ }
+
+ /**
+ * Resolve the specified {@link ProjectRequest} and return the model to use to
+ * generate the project
+ * @param request the request to handle
+ * @return a model for that request
+ */
+ protected Map resolveModel(ProjectRequest originalRequest) {
+ Assert.notNull(originalRequest.getBootVersion(), "boot version must not be null");
+ Map model = new LinkedHashMap<>();
+ InitializrMetadata metadata = metadataProvider.get();
+
+ ProjectRequest request = requestResolver.resolve(originalRequest, metadata);
+
+ // request resolved so we can log what has been requested
+ List dependencies = request.getResolvedDependencies();
+ List dependencyIds = dependencies.stream().map(Dependency::getId)
+ .collect(Collectors.toList());
+ log.info("Processing request{type=" + request.getType() + ", dependencies="
+ + dependencyIds);
+
+ if (isMavenBuild(request)) {
+ ParentPom parentPom = metadata.getConfiguration().getEnv().getMaven()
+ .resolveParentPom(request.getBootVersion());
+ if (parentPom.isIncludeSpringBootBom()
+ && !request.getBoms().containsKey("spring-boot")) {
+ request.getBoms().put("spring-boot", metadata.createSpringBootBom(
+ request.getBootVersion(), "spring-boot.version"));
+ }
+
+ model.put("mavenParentGroupId", parentPom.getGroupId());
+ model.put("mavenParentArtifactId", parentPom.getArtifactId());
+ model.put("mavenParentVersion", parentPom.getVersion());
+ model.put("includeSpringBootBom", parentPom.isIncludeSpringBootBom());
+ }
+
+ model.put("resolvedBoms",
+ request.getBoms().values().stream()
+ .sorted((a, b) -> a.getOrder().compareTo(b.getOrder()))
+ .collect(Collectors.toList()));
+
+ model.put("compileDependencies",
+ filterDependencies(dependencies, Dependency.SCOPE_COMPILE));
+ model.put("runtimeDependencies",
+ filterDependencies(dependencies, Dependency.SCOPE_RUNTIME));
+ model.put("compileOnlyDependencies",
+ filterDependencies(dependencies, Dependency.SCOPE_COMPILE_ONLY));
+ model.put("providedDependencies",
+ filterDependencies(dependencies, Dependency.SCOPE_PROVIDED));
+ model.put("testDependencies",
+ filterDependencies(dependencies, Dependency.SCOPE_TEST));
+
+ request.getBoms().forEach((k, v) -> {
+ if (v.getVersionProperty() != null) {
+ request.getBuildProperties().getVersions()
+ .computeIfAbsent(v.getVersionProperty(), key -> {
+ return () -> v.getVersion();
+ });
+ }
+ });
+
+ // Add various versions
+ model.put("dependencyManagementPluginVersion", metadata.getConfiguration()
+ .getEnv().getGradle().getDependencyManagementPluginVersion());
+ model.put("kotlinVersion",
+ metadata.getConfiguration().getEnv().getKotlin().getVersion());
+
+ // @SpringBootApplication available as from 1.2.0.RC1
+ model.put("useSpringBootApplication", VERSION_1_2_0_RC1
+ .compareTo(Version.safeParse(request.getBootVersion())) <= 0);
+
+ // Gradle plugin has changed as from 1.3.0
+ model.put("bootOneThreeAvailable", VERSION_1_3_0_M1
+ .compareTo(Version.safeParse(request.getBootVersion())) <= 0);
+
+ // Gradle plugin has changed again as from 1.4.2
+ model.put("springBootPluginName",
+ (VERSION_1_4_2_M1
+ .compareTo(Version.safeParse(request.getBootVersion())) <= 0
+ ? "org.springframework.boot" : "spring-boot"));
+
+ // New testing stuff
+ model.put("newTestInfrastructure", isNewTestInfrastructureAvailable(request));
+
+ // New Servlet Initializer location
+ model.put("newServletInitializer", isNewServletInitializerAvailable(request));
+
+ // Append the project request to the model
+ BeanWrapperImpl bean = new BeanWrapperImpl(request);
+ for (PropertyDescriptor descriptor : bean.getPropertyDescriptors()) {
+ if (bean.isReadableProperty(descriptor.getName())) {
+ model.put(descriptor.getName(),
+ bean.getPropertyValue(descriptor.getName()));
+ }
+ }
+
+ return model;
+ }
+
+ protected void setupTestModel(ProjectRequest request, Map model) {
+ String imports = "";
+ String testAnnotations = "";
+ boolean newTestInfrastructure = isNewTestInfrastructureAvailable(request);
+ if (newTestInfrastructure) {
+ imports += String.format(
+ generateImport("org.springframework.boot.test.context.SpringBootTest",
+ request.getLanguage()) + "%n");
+ imports += String.format(
+ generateImport("org.springframework.test.context.junit4.SpringRunner",
+ request.getLanguage()) + "%n");
+ }
+ else {
+ imports += String.format(generateImport(
+ "org.springframework.boot.test.SpringApplicationConfiguration",
+ request.getLanguage()) + "%n");
+ imports += String.format(generateImport(
+ "org.springframework.test.context.junit4.SpringJUnit4ClassRunner",
+ request.getLanguage()) + "%n");
+ }
+ if (request.hasWebFacet() && !newTestInfrastructure) {
+ imports += String.format(generateImport(
+ "org.springframework.test.context.web.WebAppConfiguration",
+ request.getLanguage()) + "%n");
+ testAnnotations = String.format("@WebAppConfiguration%n");
+ }
+ model.put("testImports", imports);
+ model.put("testAnnotations", testAnnotations);
+ }
+
+ protected String generateImport(String type, String language) {
+ String end = (language.equals("groovy") || language.equals("kotlin")) ? "" : ";";
+ return "import " + type + end;
+ }
+
+ private static boolean isGradleBuild(ProjectRequest request) {
+ return "gradle".equals(request.getBuild());
+ }
+
+ private static boolean isMavenBuild(ProjectRequest request) {
+ return "maven".equals(request.getBuild());
+ }
+
+ private static boolean isNewTestInfrastructureAvailable(ProjectRequest request) {
+ return VERSION_1_4_0_M2
+ .compareTo(Version.safeParse(request.getBootVersion())) <= 0;
+ }
+
+ private static boolean isNewServletInitializerAvailable(ProjectRequest request) {
+ return VERSION_1_4_0_M3
+ .compareTo(Version.safeParse(request.getBootVersion())) <= 0;
+ }
+
+ private static boolean isGradle3Available(Version bootVersion) {
+ return VERSION_2_0_0_M1.compareTo(bootVersion) <= 0;
+ }
+
+ private byte[] doGenerateMavenPom(Map model) {
+ return groovyTemplate.process("starter-pom.xml", model).getBytes();
+ }
+
+ private byte[] doGenerateGradleBuild(Map model) {
+ return groovyTemplate.process("starter-build.gradle", model).getBytes();
+ }
+
+ private void writeGradleWrapper(File dir, Version bootVersion) {
+ String gradlePrefix = isGradle3Available(bootVersion) ? "gradle3" : "gradle";
+ writeTextResource(dir, "gradlew.bat", gradlePrefix + "/gradlew.bat");
+ writeTextResource(dir, "gradlew", gradlePrefix + "/gradlew");
+
+ File wrapperDir = new File(dir, "gradle/wrapper");
+ wrapperDir.mkdirs();
+ writeTextResource(wrapperDir, "gradle-wrapper.properties",
+ gradlePrefix + "/gradle/wrapper/gradle-wrapper.properties");
+ writeBinaryResource(wrapperDir, "gradle-wrapper.jar",
+ gradlePrefix + "/gradle/wrapper/gradle-wrapper.jar");
+ }
+
+ private void writeMavenWrapper(File dir) {
+ writeTextResource(dir, "mvnw.cmd", "maven/mvnw.cmd");
+ writeTextResource(dir, "mvnw", "maven/mvnw");
+
+ File wrapperDir = new File(dir, ".mvn/wrapper");
+ wrapperDir.mkdirs();
+ writeTextResource(wrapperDir, "maven-wrapper.properties",
+ "maven/wrapper/maven-wrapper.properties");
+ writeBinaryResource(wrapperDir, "maven-wrapper.jar",
+ "maven/wrapper/maven-wrapper.jar");
+ }
+
+ private File writeBinaryResource(File dir, String name, String location) {
+ return doWriteProjectResource(dir, name, location, true);
+ }
+
+ private File writeTextResource(File dir, String name, String location) {
+ return doWriteProjectResource(dir, name, location, false);
+ }
+
+ private File doWriteProjectResource(File dir, String name, String location,
+ boolean binary) {
+ File target = new File(dir, name);
+ if (binary) {
+ writeBinary(target, projectResourceLocator
+ .getBinaryResource("classpath:project/" + location));
+ }
+ else {
+ writeText(target, projectResourceLocator
+ .getTextResource("classpath:project/" + location));
+ }
+ return target;
+ }
+
+ private File initializerProjectDir(File rootDir, ProjectRequest request) {
+ if (request.getBaseDir() != null) {
+ File dir = new File(rootDir, request.getBaseDir());
+ dir.mkdirs();
+ return dir;
+ }
+ else {
+ return rootDir;
+ }
+ }
+
+ public void write(File target, String templateName, Map model) {
+ String tmpl = templateName.endsWith(".groovy") ? templateName + ".tmpl"
+ : templateName;
+ String body = groovyTemplate.process(tmpl, model);
+ writeText(target, body);
+ }
+
+ private void writeText(File target, String body) {
+ try (OutputStream stream = new FileOutputStream(target)) {
+ StreamUtils.copy(body, Charset.forName("UTF-8"), stream);
+ }
+ catch (Exception e) {
+ throw new IllegalStateException("Cannot write file " + target, e);
+ }
+ }
+
+ private void writeBinary(File target, byte[] body) {
+ try (OutputStream stream = new FileOutputStream(target)) {
+ StreamUtils.copy(body, stream);
+ }
+ catch (Exception e) {
+ throw new IllegalStateException("Cannot write file " + target, e);
+ }
+ }
+
+ private void addTempFile(String group, File file) {
+ temporaryFiles.computeIfAbsent(group, (key) -> new ArrayList()).add(file);
+ }
+
+ private static List filterDependencies(List dependencies,
+ String scope) {
+ return dependencies.stream().filter(dep -> scope.equals(dep.getScope()))
+ .sorted((a, b) -> a.getId().compareTo(b.getId()))
+ .collect(Collectors.toList());
+ }
+
+}
diff --git a/initializr-generator/src/main/java/io/spring/initializr/generator/ProjectRequest.java b/initializr-generator/src/main/java/io/spring/initializr/generator/ProjectRequest.java
new file mode 100644
index 00000000..3b94b924
--- /dev/null
+++ b/initializr-generator/src/main/java/io/spring/initializr/generator/ProjectRequest.java
@@ -0,0 +1,311 @@
+/*
+ * Copyright 2012-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.
+ * You may obtain a copy of the License at
+ *
+ * http://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;
+
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import org.springframework.beans.BeanWrapperImpl;
+import org.springframework.util.StringUtils;
+
+import io.spring.initializr.metadata.BillOfMaterials;
+import io.spring.initializr.metadata.DefaultMetadataElement;
+import io.spring.initializr.metadata.Dependency;
+import io.spring.initializr.metadata.InitializrMetadata;
+import io.spring.initializr.metadata.Repository;
+import io.spring.initializr.metadata.Type;
+import io.spring.initializr.util.Version;
+
+/**
+ * A request to generate a project.
+ *
+ * @author Dave Syer
+ * @author Stephane Nicoll
+ */
+// @ToString(ignoreNulls = true, includePackage = false, includeNames = true)
+public class ProjectRequest extends BasicProjectRequest {
+
+ /**
+ * The id of the starter to use if no dependency is defined.
+ */
+ public static final String DEFAULT_STARTER = "root_starter";
+
+ /**
+ * Additional parameters that can be used to further identify the request.
+ */
+ private final Map parameters = new LinkedHashMap();
+
+ // Resolved dependencies based on the ids provided by either "style" or "dependencies"
+ private List resolvedDependencies;
+
+ private final Map boms = new LinkedHashMap<>();
+
+ private final Map repositories = new LinkedHashMap<>();
+
+ /**
+ * Build properties.
+ */
+ private final BuildProperties buildProperties = new BuildProperties();
+
+ private List facets = new ArrayList<>();
+ private String build;
+
+ public List getResolvedDependencies() {
+ return resolvedDependencies;
+ }
+
+ public void setResolvedDependencies(List resolvedDependencies) {
+ this.resolvedDependencies = resolvedDependencies;
+ }
+
+ public List getFacets() {
+ return facets;
+ }
+
+ public void setFacets(List facets) {
+ this.facets = facets;
+ }
+
+ public String getBuild() {
+ return build;
+ }
+
+ public void setBuild(String build) {
+ this.build = build;
+ }
+
+ public Map getParameters() {
+ return parameters;
+ }
+
+ public Map getBoms() {
+ return boms;
+ }
+
+ public Map getRepositories() {
+ return repositories;
+ }
+
+ public BuildProperties getBuildProperties() {
+ return buildProperties;
+ }
+
+ /**
+ * Initializes this instance with the defaults defined in the specified
+ * {@link InitializrMetadata}.
+ */
+ public void initialize(InitializrMetadata metadata) {
+ BeanWrapperImpl bean = new BeanWrapperImpl(this);
+ metadata.defaults().forEach((key, value) -> {
+ if (bean.isWritableProperty(key)) {
+ bean.setPropertyValue(key, value);
+ }
+ });
+ }
+
+ /**
+ * Resolve this instance against the specified {@link InitializrMetadata}
+ */
+ public void resolve(InitializrMetadata metadata) {
+ List depIds = !getStyle().isEmpty() ? getStyle() : getDependencies();
+ String actualBootVersion = getBootVersion() != null ? getBootVersion()
+ : metadata.getBootVersions().getDefault().getId();
+ Version requestedVersion = Version.parse(actualBootVersion);
+ this.resolvedDependencies = depIds.stream().map(it -> {
+ Dependency dependency = metadata.getDependencies().get(it);
+ if (dependency == null) {
+ throw new InvalidProjectRequestException(
+ "Unknown dependency '" + it + "' check project metadata");
+ }
+ return dependency.resolve(requestedVersion);
+ }).collect(Collectors.toList());
+ this.resolvedDependencies.forEach(it -> {
+ it.getFacets().forEach(facet -> {
+ if (!facets.contains(facet)) {
+ facets.add(facet);
+ }
+ });
+ if (!it.match(requestedVersion)) {
+ throw new InvalidProjectRequestException(
+ "Dependency '" + it.getId() + "' is not compatible "
+ + "with Spring Boot " + requestedVersion);
+ }
+ if (it.getBom() != null) {
+ resolveBom(metadata, it.getBom(), requestedVersion);
+ }
+ if (it.getRepository() != null) {
+ String repositoryId = it.getRepository();
+ this.repositories.computeIfAbsent(repositoryId, s -> metadata
+ .getConfiguration().getEnv().getRepositories().get(s));
+ }
+ });
+ if (getType() != null) {
+ Type type = metadata.getTypes().get(getType());
+ if (type == null) {
+ throw new InvalidProjectRequestException(
+ "Unknown type '" + getType() + "' check project metadata");
+ }
+ String buildTag = type.getTags().get("build");
+ if (buildTag != null) {
+ this.build = buildTag;
+ }
+ }
+ if (getPackaging() != null) {
+ DefaultMetadataElement packaging = metadata.getPackagings()
+ .get(getPackaging());
+ if (packaging == null) {
+ throw new InvalidProjectRequestException("Unknown packaging '"
+ + getPackaging() + "' check project metadata");
+ }
+ }
+ if (getLanguage() != null) {
+ DefaultMetadataElement language = metadata.getLanguages().get(getLanguage());
+ if (language == null) {
+ throw new InvalidProjectRequestException("Unknown language '"
+ + getLanguage() + "' check project metadata");
+ }
+ }
+
+ if (!StringUtils.hasText(getApplicationName())) {
+ setApplicationName(
+ metadata.getConfiguration().generateApplicationName(getName()));
+ }
+ setPackageName(metadata.getConfiguration().cleanPackageName(getPackageName(),
+ metadata.getPackageName().getContent()));
+
+ initializeRepositories(metadata, requestedVersion);
+
+ initializeProperties(metadata);
+
+ afterResolution(metadata);
+ }
+
+ /**
+ * Set the repositories that this instance should use based on the
+ * {@link InitializrMetadata} and the requested Spring Boot {@link Version}.
+ */
+ protected void initializeRepositories(InitializrMetadata metadata,
+ Version requestedVersion) {
+ if (!"RELEASE".equals(requestedVersion.getQualifier().getQualifier())) {
+ repositories.put("spring-snapshots", metadata.getConfiguration().getEnv()
+ .getRepositories().get("spring-snapshots"));
+ repositories.put("spring-milestones", metadata.getConfiguration().getEnv()
+ .getRepositories().get("spring-milestones"));
+ }
+ boms.values().forEach(it -> {
+ it.getRepositories().forEach(key -> {
+ repositories.computeIfAbsent(key, s -> metadata.getConfiguration()
+ .getEnv().getRepositories().get(s));
+ });
+ });
+ }
+
+ protected void initializeProperties(InitializrMetadata metadata) {
+ if ("gradle".equals(build)) {
+ buildProperties.getGradle().put("springBootVersion", this::getBootVersion);
+ if ("kotlin".equals(getLanguage())) {
+ buildProperties.getGradle().put("kotlinVersion", () -> metadata
+ .getConfiguration().getEnv().getKotlin().getVersion());
+ }
+ }
+ else {
+ buildProperties.getMaven().put("project.build.sourceEncoding", () -> "UTF-8");
+ buildProperties.getMaven().put("project.reporting.outputEncoding",
+ () -> "UTF-8");
+ buildProperties.getVersions().put("java.version", this::getJavaVersion);
+ if ("kotlin".equals(getLanguage())) {
+ buildProperties.getVersions().put("kotlin.version", () -> metadata
+ .getConfiguration().getEnv().getKotlin().getVersion());
+ }
+ }
+ }
+
+ private void resolveBom(InitializrMetadata metadata, String bomId,
+ Version requestedVersion) {
+ boms.computeIfAbsent(bomId, key -> {
+ BillOfMaterials bom = metadata.getConfiguration().getEnv().getBoms().get(key)
+ .resolve(requestedVersion);
+ bom.getAdditionalBoms()
+ .forEach(id -> resolveBom(metadata, id, requestedVersion));
+ return bom;
+ });
+ }
+
+ /**
+ * Update this request once it has been resolved with the specified
+ * {@link InitializrMetadata}.
+ */
+ protected void afterResolution(InitializrMetadata metadata) {
+ if ("war".equals(getPackaging())) {
+ if (!hasWebFacet()) {
+ // Need to be able to bootstrap the web app
+ resolvedDependencies.add(metadata.getDependencies().get("web"));
+ facets.add("web");
+ }
+ // Add the tomcat starter in provided scope
+ Dependency tomcat = new Dependency().asSpringBootStarter("tomcat");
+ tomcat.setScope(Dependency.SCOPE_PROVIDED);
+ resolvedDependencies.add(tomcat);
+ }
+ if (!resolvedDependencies.stream().anyMatch(it -> it.isStarter())) {
+ // There"s no starter so we add the default one
+ addDefaultDependency();
+ }
+ }
+
+ /**
+ * Add a default dependency if the project does not define any dependency
+ */
+ protected void addDefaultDependency() {
+ Dependency root = new Dependency();
+ root.setId(DEFAULT_STARTER);
+ root.asSpringBootStarter("");
+ resolvedDependencies.add(root);
+ }
+
+ /**
+ * Specify if this request has the web facet enabled.
+ */
+ public boolean hasWebFacet() {
+ return hasFacet("web");
+ }
+
+ /**
+ * Specify if this request has the specified facet enabled
+ */
+ public boolean hasFacet(String facet) {
+ return facets.contains(facet);
+ }
+
+ @Override
+ public String toString() {
+ return "ProjectRequest ["
+ + (parameters != null ? "parameters=" + parameters + ", " : "")
+ + (resolvedDependencies != null
+ ? "resolvedDependencies=" + resolvedDependencies + ", " : "")
+ + (boms != null ? "boms=" + boms + ", " : "")
+ + (repositories != null ? "repositories=" + repositories + ", " : "")
+ + (buildProperties != null ? "buildProperties=" + buildProperties + ", "
+ : "")
+ + (facets != null ? "facets=" + facets + ", " : "")
+ + (build != null ? "build=" + build : "") + "]";
+ }
+
+}
diff --git a/initializr-generator/src/main/groovy/io/spring/initializr/generator/ProjectRequestEvent.groovy b/initializr-generator/src/main/java/io/spring/initializr/generator/ProjectRequestEvent.java
similarity index 72%
rename from initializr-generator/src/main/groovy/io/spring/initializr/generator/ProjectRequestEvent.groovy
rename to initializr-generator/src/main/java/io/spring/initializr/generator/ProjectRequestEvent.java
index 9096b2d3..d546e6bb 100644
--- a/initializr-generator/src/main/groovy/io/spring/initializr/generator/ProjectRequestEvent.groovy
+++ b/initializr-generator/src/main/java/io/spring/initializr/generator/ProjectRequestEvent.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package io.spring.initializr.generator
+package io.spring.initializr.generator;
/**
* Event published when a {@link ProjectRequest} has been processed.
@@ -23,21 +23,29 @@ package io.spring.initializr.generator
* @see ProjectGeneratedEvent
* @see ProjectFailedEvent
*/
-abstract class ProjectRequestEvent {
+public abstract class ProjectRequestEvent {
/**
* The {@link ProjectRequest} used to generate the project.
*/
- final ProjectRequest projectRequest
+ private final ProjectRequest projectRequest;
/**
* The timestamp at which the request was processed.
*/
- final long timestamp
+ private final long timestamp;
protected ProjectRequestEvent(ProjectRequest projectRequest) {
- this.projectRequest = projectRequest
- this.timestamp = System.currentTimeMillis()
+ this.projectRequest = projectRequest;
+ this.timestamp = System.currentTimeMillis();
+ }
+
+ public ProjectRequest getProjectRequest() {
+ return projectRequest;
+ }
+
+ public long getTimestamp() {
+ return timestamp;
}
}
diff --git a/initializr-generator/src/main/groovy/io/spring/initializr/generator/ProjectRequestPostProcessor.groovy b/initializr-generator/src/main/java/io/spring/initializr/generator/ProjectRequestPostProcessor.java
similarity index 93%
rename from initializr-generator/src/main/groovy/io/spring/initializr/generator/ProjectRequestPostProcessor.groovy
rename to initializr-generator/src/main/java/io/spring/initializr/generator/ProjectRequestPostProcessor.java
index fa67a008..588facdc 100644
--- a/initializr-generator/src/main/groovy/io/spring/initializr/generator/ProjectRequestPostProcessor.groovy
+++ b/initializr-generator/src/main/java/io/spring/initializr/generator/ProjectRequestPostProcessor.java
@@ -14,9 +14,9 @@
* limitations under the License.
*/
-package io.spring.initializr.generator
+package io.spring.initializr.generator;
-import io.spring.initializr.metadata.InitializrMetadata
+import io.spring.initializr.metadata.InitializrMetadata;
/**
* Project generation hook that allows for custom modification of {@link ProjectRequest}
@@ -25,7 +25,7 @@ import io.spring.initializr.metadata.InitializrMetadata
*
* @author Stephane Nicoll
*/
-interface ProjectRequestPostProcessor {
+public interface ProjectRequestPostProcessor {
/**
* Apply this post processor to the given {@code ProjectRequest} before it
diff --git a/initializr-generator/src/main/java/io/spring/initializr/generator/ProjectRequestPostProcessorAdapter.java b/initializr-generator/src/main/java/io/spring/initializr/generator/ProjectRequestPostProcessorAdapter.java
new file mode 100644
index 00000000..8ec589f9
--- /dev/null
+++ b/initializr-generator/src/main/java/io/spring/initializr/generator/ProjectRequestPostProcessorAdapter.java
@@ -0,0 +1,21 @@
+package io.spring.initializr.generator;
+
+import io.spring.initializr.metadata.InitializrMetadata;
+
+/**
+ * An implementation of {@link ProjectRequestPostProcessor} with empty methods allowing
+ * sub-classes to override only the methods they're interested in.
+ *
+ * @author Stephane Nicoll
+ */
+public class ProjectRequestPostProcessorAdapter implements ProjectRequestPostProcessor {
+
+ @Override
+ public void postProcessBeforeResolution(ProjectRequest request, InitializrMetadata metadata) {
+ }
+
+ @Override
+ public void postProcessAfterResolution(ProjectRequest request, InitializrMetadata metadata) {
+ }
+
+}
diff --git a/initializr-generator/src/main/java/io/spring/initializr/generator/ProjectRequestResolver.java b/initializr-generator/src/main/java/io/spring/initializr/generator/ProjectRequestResolver.java
new file mode 100644
index 00000000..9e71cb51
--- /dev/null
+++ b/initializr-generator/src/main/java/io/spring/initializr/generator/ProjectRequestResolver.java
@@ -0,0 +1,43 @@
+package io.spring.initializr.generator;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.springframework.util.Assert;
+
+import io.spring.initializr.metadata.InitializrMetadata;
+
+/**
+ * Resolve {@link ProjectRequest} instances, honouring callback hook points.
+ *
+ * @author Stephane Nicoll
+ */
+public class ProjectRequestResolver {
+
+ private final List postProcessors;
+
+ public ProjectRequestResolver(List postProcessors) {
+ this.postProcessors = new ArrayList<>(postProcessors);
+ }
+
+ public ProjectRequest resolve(ProjectRequest request, InitializrMetadata metadata) {
+ Assert.notNull(request, "Request must not be null");
+ applyPostProcessBeforeResolution(request, metadata);
+ request.resolve(metadata);
+ applyPostProcessAfterResolution(request, metadata);
+ return request;
+ }
+
+ private void applyPostProcessBeforeResolution(ProjectRequest request, InitializrMetadata metadata) {
+ for (ProjectRequestPostProcessor processor : postProcessors) {
+ processor.postProcessBeforeResolution(request, metadata);
+ }
+ }
+
+ private void applyPostProcessAfterResolution(ProjectRequest request, InitializrMetadata metadata) {
+ for (ProjectRequestPostProcessor processor : postProcessors) {
+ processor.postProcessAfterResolution(request, metadata);
+ }
+ }
+
+}
diff --git a/initializr-generator/src/main/groovy/io/spring/initializr/generator/ProjectResourceLocator.groovy b/initializr-generator/src/main/java/io/spring/initializr/generator/ProjectResourceLocator.java
similarity index 51%
rename from initializr-generator/src/main/groovy/io/spring/initializr/generator/ProjectResourceLocator.groovy
rename to initializr-generator/src/main/java/io/spring/initializr/generator/ProjectResourceLocator.java
index 716ff029..6af04a77 100644
--- a/initializr-generator/src/main/groovy/io/spring/initializr/generator/ProjectResourceLocator.groovy
+++ b/initializr-generator/src/main/java/io/spring/initializr/generator/ProjectResourceLocator.java
@@ -14,22 +14,24 @@
* limitations under the License.
*/
-package io.spring.initializr.generator
+package io.spring.initializr.generator;
-import java.nio.charset.Charset
+import java.io.InputStream;
+import java.net.URL;
+import java.nio.charset.Charset;
-import org.springframework.cache.annotation.Cacheable
-import org.springframework.util.ResourceUtils
-import org.springframework.util.StreamUtils
+import org.springframework.cache.annotation.Cacheable;
+import org.springframework.util.ResourceUtils;
+import org.springframework.util.StreamUtils;
/**
* Locate project resources.
*
* @author Stephane Nicoll
*/
-class ProjectResourceLocator {
+public class ProjectResourceLocator {
- private static final Charset UTF_8 = Charset.forName("UTF-8")
+ private static final Charset UTF_8 = Charset.forName("UTF-8");
/**
* Return the binary content of the resource at the specified location.
@@ -37,12 +39,12 @@ class ProjectResourceLocator {
* @return the content of the resource
*/
@Cacheable("project-resources")
- byte[] getBinaryResource(String location) {
- InputStream stream = getInputStream(location)
- try {
- return StreamUtils.copyToByteArray(stream)
- } finally {
- stream.close()
+ public byte[] getBinaryResource(String location) {
+ try (InputStream stream = getInputStream(location)) {
+ return StreamUtils.copyToByteArray(stream);
+ }
+ catch (Exception e) {
+ throw new IllegalStateException("Cannot get resource", e);
}
}
@@ -52,19 +54,20 @@ class ProjectResourceLocator {
* @return the content of the resource
*/
@Cacheable("project-resources")
- String getTextResource(String location) {
- InputStream stream = getInputStream(location)
- try {
- return StreamUtils.copyToString(stream, UTF_8)
- } finally {
- stream.close()
+ public String getTextResource(String location) {
+ try (InputStream stream = getInputStream(location)) {
+ return StreamUtils.copyToString(stream, UTF_8);
}
+ catch (Exception e) {
+ throw new IllegalStateException("Cannot get resource", e);
+ }
+
}
- private InputStream getInputStream(String location) {
- def url = ResourceUtils.getURL(location)
- def stream = url.openStream()
- stream
+ private InputStream getInputStream(String location) throws Exception {
+ URL url = ResourceUtils.getURL(location);
+ InputStream stream = url.openStream();
+ return stream;
}
}
diff --git a/initializr-generator/src/main/java/io/spring/initializr/metadata/BillOfMaterials.java b/initializr-generator/src/main/java/io/spring/initializr/metadata/BillOfMaterials.java
new file mode 100644
index 00000000..afa81769
--- /dev/null
+++ b/initializr-generator/src/main/java/io/spring/initializr/metadata/BillOfMaterials.java
@@ -0,0 +1,315 @@
+/*
+ * Copyright 2012-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.
+ * You may obtain a copy of the License at
+ *
+ * http://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.metadata;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonInclude;
+
+import io.spring.initializr.util.InvalidVersionException;
+import io.spring.initializr.util.Version;
+import io.spring.initializr.util.VersionParser;
+import io.spring.initializr.util.VersionRange;
+
+/**
+ * Define a Bill Of Materials to be represented in the generated project if a dependency
+ * refers to it.
+ *
+ * @author Stephane Nicoll
+ */
+@JsonInclude(JsonInclude.Include.NON_DEFAULT)
+public class BillOfMaterials {
+
+ private String groupId;
+ private String artifactId;
+
+ /**
+ * The version of the BOM. Can be {@code null} if it is provided via a mapping.
+ */
+ private String version;
+
+ /**
+ * The property to use to externalize the version of the BOM. When this is set, a
+ * version property is automatically added rather than setting the version in the bom
+ * declaration itself.
+ */
+ private String versionProperty;
+
+ /**
+ * The relative order of this BOM where lower values have higher priority. The default
+ * value is {@code Integer.MAX_VALUE}, indicating lowest priority. The Spring Boot
+ * dependencies bom has an order of 100.
+ */
+ private Integer order = Integer.MAX_VALUE;
+
+ /**
+ * The BOM(s) that should be automatically included if this BOM is required. Can be
+ * {@code null} if it is provided via a mapping.
+ */
+ private List additionalBoms = new ArrayList<>();
+
+ /**
+ * The repositories that are required if this BOM is required. Can be {@code null} if
+ * it is provided via a mapping.
+ */
+ private List repositories = new ArrayList<>();
+
+ private final List mappings = new ArrayList<>();
+
+ public BillOfMaterials() {
+ }
+
+ private BillOfMaterials(String groupId, String artifactId) {
+ this(groupId, artifactId, null);
+ }
+
+ private BillOfMaterials(String groupId, String artifactId, String version) {
+ this.groupId = groupId;
+ this.artifactId = artifactId;
+ this.version = version;
+ }
+
+ public String getGroupId() {
+ return groupId;
+ }
+
+ public void setGroupId(String groupId) {
+ this.groupId = groupId;
+ }
+
+ public String getArtifactId() {
+ return artifactId;
+ }
+
+ public void setArtifactId(String artifactId) {
+ this.artifactId = artifactId;
+ }
+
+ public String getVersion() {
+ return version;
+ }
+
+ public void setVersion(String version) {
+ this.version = version;
+ }
+
+ public String getVersionProperty() {
+ return versionProperty;
+ }
+
+ public void setVersionProperty(String versionProperty) {
+ this.versionProperty = versionProperty;
+ }
+
+ public Integer getOrder() {
+ return order;
+ }
+
+ public void setOrder(Integer order) {
+ this.order = order;
+ }
+
+ public List getAdditionalBoms() {
+ return additionalBoms;
+ }
+
+ public void setAdditionalBoms(List additionalBoms) {
+ this.additionalBoms = additionalBoms;
+ }
+
+ public List getRepositories() {
+ return repositories;
+ }
+
+ public void setRepositories(List repositories) {
+ this.repositories = repositories;
+ }
+
+ public List getMappings() {
+ return mappings;
+ }
+
+ /**
+ * Determine the version placeholder to use for this instance. If a version property
+ * is defined, this returns the reference for the property. Otherwise this returns the
+ * plain {@link #version}
+ */
+ public String determineVersionToken() {
+ return (versionProperty != null ? "${" + versionProperty + "}" : version);
+ }
+
+ public void validate() {
+ if (version == null && mappings.isEmpty()) {
+ throw new InvalidInitializrMetadataException(
+ "No version available for " + this);
+ }
+ updateVersionRange(VersionParser.DEFAULT);
+ }
+
+ public void updateVersionRange(VersionParser versionParser) {
+ mappings.forEach(it -> {
+ try {
+ it.range = versionParser.parseRange(it.versionRange);
+ }
+ catch (InvalidVersionException ex) {
+ throw new InvalidInitializrMetadataException(
+ "Invalid version range " + it.versionRange + " for " + this, ex);
+ }
+ });
+ }
+
+ /**
+ * Resolve this instance according to the specified Spring Boot {@link Version}.
+ * Return a {@link BillOfMaterials} instance that holds the version, repositories and
+ * additional BOMs to use, if any.
+ */
+ public BillOfMaterials resolve(Version bootVersion) {
+ if (mappings.isEmpty()) {
+ return this;
+ }
+
+ for (Mapping mapping : mappings) {
+ if (mapping.range.match(bootVersion)) {
+ BillOfMaterials resolvedBom = new BillOfMaterials(groupId, artifactId,
+ mapping.version);
+ resolvedBom.setVersionProperty(versionProperty);
+ resolvedBom.setOrder(order);
+ resolvedBom.repositories.addAll(!mapping.repositories.isEmpty()
+ ? mapping.repositories : repositories);
+ resolvedBom.additionalBoms.addAll(!mapping.additionalBoms.isEmpty()
+ ? mapping.additionalBoms : additionalBoms);
+ return resolvedBom;
+ }
+ }
+ throw new IllegalStateException(
+ "No suitable mapping was found for " + this + " and version " + bootVersion);
+ }
+
+ @Override
+ public String toString() {
+ return "BillOfMaterials [" + (groupId != null ? "groupId=" + groupId + ", " : "")
+ + (artifactId != null ? "artifactId=" + artifactId + ", " : "")
+ + (version != null ? "version=" + version + ", " : "")
+ + (versionProperty != null ? "versionProperty=" + versionProperty + ", "
+ : "")
+ + (order != null ? "order=" + order + ", " : "")
+ + (additionalBoms != null ? "additionalBoms=" + additionalBoms + ", "
+ : "")
+ + (repositories != null ? "repositories=" + repositories : "") + "]";
+ }
+
+ public static class Mapping {
+
+ private String versionRange;
+
+ private String version;
+
+ private List repositories = new ArrayList<>();
+
+ private List additionalBoms = new ArrayList<>();
+
+ @JsonIgnore
+ private VersionRange range;
+
+ public Mapping() {
+ }
+
+ private Mapping(String range, String version, String... repositories) {
+ this.versionRange = range;
+ this.version = version;
+ this.repositories.addAll(Arrays.asList(repositories));
+ }
+
+ public String determineVersionRangeRequirement() {
+ return range.toString();
+ }
+
+ public static Mapping create(String range, String version) {
+ return new Mapping(range, version);
+ }
+
+ public static Mapping create(String range, String version,
+ String... repositories) {
+ return new Mapping(range, version, repositories);
+ }
+
+ public String getVersionRange() {
+ return versionRange;
+ }
+
+ public String getVersion() {
+ return version;
+ }
+
+ public List getRepositories() {
+ return repositories;
+ }
+
+ public List getAdditionalBoms() {
+ return additionalBoms;
+ }
+
+ public VersionRange getRange() {
+ return range;
+ }
+
+ public void setVersionRange(String versionRange) {
+ this.versionRange = versionRange;
+ }
+
+ public void setVersion(String version) {
+ this.version = version;
+ }
+
+ public void setRepositories(List repositories) {
+ this.repositories = repositories;
+ }
+
+ public void setAdditionalBoms(List additionalBoms) {
+ this.additionalBoms = additionalBoms;
+ }
+
+ public void setRange(VersionRange range) {
+ this.range = range;
+ }
+
+ @Override
+ public String toString() {
+ return "Mapping ["
+ + (versionRange != null ? "versionRange=" + versionRange + ", " : "")
+ + (version != null ? "version=" + version + ", " : "")
+ + (repositories != null ? "repositories=" + repositories + ", " : "")
+ + (additionalBoms != null ? "additionalBoms=" + additionalBoms + ", "
+ : "")
+ + (range != null ? "range=" + range : "") + "]";
+ }
+
+ }
+
+ public static BillOfMaterials create(String groupId, String artifactId) {
+ return new BillOfMaterials(groupId, artifactId);
+ }
+
+ public static BillOfMaterials create(String groupId, String artifactId,
+ String version) {
+ return new BillOfMaterials(groupId, artifactId, version);
+ }
+
+}
diff --git a/initializr-generator/src/main/java/io/spring/initializr/metadata/DefaultMetadataElement.java b/initializr-generator/src/main/java/io/spring/initializr/metadata/DefaultMetadataElement.java
new file mode 100644
index 00000000..d74d3b17
--- /dev/null
+++ b/initializr-generator/src/main/java/io/spring/initializr/metadata/DefaultMetadataElement.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2012-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.
+ * You may obtain a copy of the License at
+ *
+ * http://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.metadata;
+
+/**
+ * A {@link MetadataElement} that specifies if its
+ * the default for a given capability.
+ *
+ * @author Stephane Nicoll
+ */
+public class DefaultMetadataElement extends MetadataElement {
+
+ private boolean defaultValue;
+
+ public DefaultMetadataElement() {
+ }
+
+ public DefaultMetadataElement(String id, String name, boolean defaultValue) {
+ super(id, name);
+ this.defaultValue = defaultValue;
+ }
+
+ public DefaultMetadataElement(String id, boolean defaultValue) {
+ this(id, null, defaultValue);
+ }
+
+ public void setDefault(boolean defaultValue) {
+ this.defaultValue = defaultValue;
+ }
+
+ public boolean isDefault() {
+ return this.defaultValue;
+ }
+
+ public static DefaultMetadataElement create(String id, boolean defaultValue) {
+ return new DefaultMetadataElement(id, defaultValue);
+ }
+
+ public static DefaultMetadataElement create(String id, String name, boolean defaultValue) {
+ return new DefaultMetadataElement(id, name, defaultValue);
+ }
+
+}
diff --git a/initializr-generator/src/main/groovy/io/spring/initializr/InitializrException.groovy b/initializr-generator/src/main/java/io/spring/initializr/metadata/Defaultable.java
similarity index 74%
rename from initializr-generator/src/main/groovy/io/spring/initializr/InitializrException.groovy
rename to initializr-generator/src/main/java/io/spring/initializr/metadata/Defaultable.java
index 0c049bd6..5e0a8079 100644
--- a/initializr-generator/src/main/groovy/io/spring/initializr/InitializrException.groovy
+++ b/initializr-generator/src/main/java/io/spring/initializr/metadata/Defaultable.java
@@ -14,15 +14,8 @@
* limitations under the License.
*/
-package io.spring.initializr
+package io.spring.initializr.metadata;
-import groovy.transform.InheritConstructors
-
-/**
- * Base Initializr exception.
- *
- * @author Stephane Nicoll
- */
-@InheritConstructors
-class InitializrException extends RuntimeException {
+public interface Defaultable {
+ T getDefault();
}
diff --git a/initializr-generator/src/main/java/io/spring/initializr/metadata/DependenciesCapability.java b/initializr-generator/src/main/java/io/spring/initializr/metadata/DependenciesCapability.java
new file mode 100644
index 00000000..665a1105
--- /dev/null
+++ b/initializr-generator/src/main/java/io/spring/initializr/metadata/DependenciesCapability.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2012-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.
+ * You may obtain a copy of the License at
+ *
+ * http://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.metadata;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+
+import io.spring.initializr.util.VersionParser;
+
+/**
+ * A {@link ServiceCapability} listing the available dependencies defined as a
+ * {@link ServiceCapabilityType#HIERARCHICAL_MULTI_SELECT} capability.
+ *
+ * @author Stephane Nicoll
+ */
+public class DependenciesCapability extends ServiceCapability> {
+
+ final List content = new ArrayList<>();
+
+ @JsonIgnore
+ private final Map indexedDependencies = new LinkedHashMap<>();
+
+ public DependenciesCapability() {
+ super("dependencies", ServiceCapabilityType.HIERARCHICAL_MULTI_SELECT,
+ "Project dependencies", "dependency identifiers (comma-separated)");
+ }
+
+ public List getContent() {
+ return content;
+ }
+
+ /**
+ * Return the {@link Dependency} with the specified id or {@code null} if no such
+ * dependency exists.
+ */
+ public Dependency get(String id) {
+ return indexedDependencies.get(id);
+ }
+
+ /**
+ * Return all dependencies as a flat collection
+ */
+ public Collection getAll() {
+ return Collections.unmodifiableCollection(indexedDependencies.values());
+ }
+
+ public void validate() {
+ index();
+ }
+
+ public void updateVersionRange(VersionParser versionParser) {
+ indexedDependencies.values().forEach(it -> {
+ it.updateVersionRanges(versionParser);
+ });
+ }
+
+ @Override
+ public void merge(List otherContent) {
+ otherContent.forEach(group -> {
+ if (!content.stream().anyMatch(it -> group.getName() != null
+ && group.getName().equals(it.getName()))) {
+ content.add(group);
+ }
+ });
+ index();
+ }
+
+ private void index() {
+ indexedDependencies.clear();
+ content.forEach(group -> {
+ group.content.forEach(dependency -> {
+ // Apply defaults
+ if (dependency.getVersionRange() == null
+ && group.getVersionRange() != null) {
+ dependency.setVersionRange(group.getVersionRange());
+ }
+ if (dependency.getBom() == null && group.getBom() != null) {
+ dependency.setBom(group.getBom());
+ }
+ if (dependency.getRepository() == null && group.getRepository() != null) {
+ dependency.setRepository(group.getRepository());
+ }
+
+ dependency.resolve();
+ indexDependency(dependency.getId(), dependency);
+ for (String alias : dependency.getAliases()) {
+ indexDependency(alias, dependency);
+ }
+ });
+ });
+ }
+
+ private void indexDependency(String id, Dependency dependency) {
+ Dependency existing = indexedDependencies.get(id);
+ if (existing != null) {
+ throw new IllegalArgumentException(
+ "Could not register " + dependency + " another dependency "
+ + "has also the '" + id + "' id " + existing);
+ }
+ indexedDependencies.put(id, dependency);
+ }
+
+}
diff --git a/initializr-generator/src/main/java/io/spring/initializr/metadata/Dependency.java b/initializr-generator/src/main/java/io/spring/initializr/metadata/Dependency.java
new file mode 100644
index 00000000..30d841c0
--- /dev/null
+++ b/initializr-generator/src/main/java/io/spring/initializr/metadata/Dependency.java
@@ -0,0 +1,513 @@
+/*
+ * Copyright 2012-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.
+ * You may obtain a copy of the License at
+ *
+ * http://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.metadata;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.StringTokenizer;
+
+import org.springframework.util.StringUtils;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonInclude;
+
+import io.spring.initializr.util.InvalidVersionException;
+import io.spring.initializr.util.Version;
+import io.spring.initializr.util.VersionParser;
+import io.spring.initializr.util.VersionRange;
+
+/**
+ * Meta-data for a dependency. Each dependency has a primary identifier and an arbitrary
+ * number of {@code aliases}.
+ *
+ * @author Stephane Nicoll
+ */
+@JsonInclude(JsonInclude.Include.NON_EMPTY)
+// @AutoClone(style = AutoCloneStyle.COPY_CONSTRUCTOR)
+public class Dependency extends MetadataElement implements Describable {
+
+ public static final String SCOPE_COMPILE = "compile";
+ public static final String SCOPE_COMPILE_ONLY = "compileOnly";
+ public static final String SCOPE_RUNTIME = "runtime";
+ public static final String SCOPE_PROVIDED = "provided";
+ public static final String SCOPE_TEST = "test";
+ public static final List SCOPE_ALL = Arrays.asList(SCOPE_COMPILE,
+ SCOPE_RUNTIME, SCOPE_COMPILE_ONLY, SCOPE_PROVIDED, SCOPE_TEST);
+
+ private List aliases = new ArrayList<>();
+
+ private List facets = new ArrayList<>();
+
+ private String groupId;
+
+ private String artifactId;
+
+ /**
+ * The default version, can be {@code null} to indicate that the version is managed by
+ * the project and does not need to be specified.
+ */
+ private String version;
+
+ /**
+ * The type, can be {@code null} to indicate that the default type should be used
+ * (i.e. {@code jar}).
+ */
+ private String type;
+
+ /**
+ * Dependency mapping if an attribute of the dependency differs according to the
+ * Spring Boot version. If no mapping matches, default attributes are used.
+ */
+ private List mappings = new ArrayList<>();
+
+ private String scope = SCOPE_COMPILE;
+
+ private String description;
+
+ private String versionRange;
+
+ @JsonIgnore
+ private String versionRequirement;
+
+ @JsonIgnore
+ private VersionRange range;
+
+ private String bom;
+
+ private String repository;
+
+ @JsonInclude(JsonInclude.Include.NON_DEFAULT)
+ private int weight;
+
+ /**
+ * Specify if the dependency represents a "starter", i.e. the sole presence of that
+ * dependency is enough to bootstrap the context.
+ */
+ private boolean starter = true;
+
+ private List keywords = new ArrayList<>();
+
+ private List links = new ArrayList<>();
+
+ public Dependency() {
+ }
+
+ public Dependency(Dependency dependency) {
+ super(dependency);
+ this.aliases.addAll(dependency.aliases);
+ this.facets.addAll(dependency.facets);
+ this.groupId = dependency.groupId;
+ this.artifactId = dependency.artifactId;
+ this.version = dependency.version;
+ this.type = dependency.type;
+ this.mappings.addAll(dependency.mappings);
+ this.scope = dependency.scope;
+ this.description = dependency.description;
+ this.versionRange = dependency.versionRange;
+ this.versionRequirement = dependency.versionRequirement;
+ this.range = dependency.range;
+ this.bom = dependency.bom;
+ this.repository = dependency.repository;
+ this.weight = dependency.weight;
+ this.starter = dependency.starter;
+ this.keywords.addAll(dependency.keywords);
+ this.links.addAll(dependency.links);
+ }
+
+ public void setScope(String scope) {
+ if (!SCOPE_ALL.contains(scope)) {
+ throw new InvalidInitializrMetadataException(
+ "Invalid scope " + scope + " must be one of " + SCOPE_ALL);
+ }
+ this.scope = scope;
+ }
+
+ public void setVersionRange(String versionRange) {
+ this.versionRange = StringUtils.hasText(versionRange) ? versionRange.trim()
+ : null;
+ }
+
+ /**
+ * Specify if the dependency has its coordinates set, i.e. {@code groupId} and
+ * {@code artifactId}.
+ */
+ public boolean hasCoordinates() {
+ return groupId != null && artifactId != null;
+ }
+
+ /**
+ * Define this dependency as a standard spring boot starter with the specified name
+ *
+ * If no name is specified, the root "spring-boot-starter" is assumed.
+ */
+ public Dependency asSpringBootStarter(String name) {
+ groupId = "org.springframework.boot";
+ artifactId = StringUtils.hasText(name) ? "spring-boot-starter-" + name
+ : "spring-boot-starter";
+ if (StringUtils.hasText(name)) {
+ setId(name);
+ }
+ return this;
+ }
+
+ /**
+ * Validate the dependency and complete its state based on the available information.
+ */
+ public void resolve() {
+ if (getId() == null) {
+ if (!hasCoordinates()) {
+ throw new InvalidInitializrMetadataException(
+ "Invalid dependency, should have at least an id or a groupId/artifactId pair.");
+ }
+ generateId();
+ }
+ else if (!hasCoordinates()) {
+ // Let"s build the coordinates from the id
+ StringTokenizer st = new StringTokenizer(getId(), ":");
+ if (st.countTokens() == 1) { // assume spring-boot-starter
+ asSpringBootStarter(getId());
+ }
+ else if (st.countTokens() == 2 || st.countTokens() == 3) {
+ groupId = st.nextToken();
+ artifactId = st.nextToken();
+ if (st.hasMoreTokens()) {
+ version = st.nextToken();
+ }
+ }
+ else {
+ throw new InvalidInitializrMetadataException(
+ "Invalid dependency, id should have the form groupId:artifactId[:version] but got "
+ + getId());
+ }
+ }
+ links.forEach(Link::resolve);
+ updateVersionRanges(VersionParser.DEFAULT);
+ }
+
+ public void updateVersionRanges(VersionParser versionParser) {
+ if (versionRange != null) {
+ try {
+ range = versionParser.parseRange(versionRange);
+ versionRequirement = range.toString();
+ }
+ catch (InvalidVersionException ex) {
+ throw new InvalidInitializrMetadataException("Invalid version range '"
+ + versionRange + " for " + "dependency with id '" + getId() + "'",
+ ex);
+ }
+ }
+ mappings.forEach(it -> {
+ try {
+ it.range = versionParser.parseRange(it.versionRange);
+ }
+ catch (InvalidVersionException ex) {
+ throw new InvalidInitializrMetadataException(
+ "Invalid version range " + it.versionRange + " for " + this, ex);
+ }
+ });
+ }
+
+ /**
+ * Resolve this instance according to the specified Spring Boot {@link Version}.
+ * Return a {@link Dependency} instance that has its state resolved against the
+ * specified version.
+ */
+ public Dependency resolve(Version bootVersion) {
+ for (Mapping mapping : mappings) {
+ if (mapping.range.match(bootVersion)) {
+ Dependency dependency = new Dependency(this);
+ dependency.groupId = mapping.groupId != null ? mapping.groupId
+ : this.groupId;
+ dependency.artifactId = mapping.artifactId != null ? mapping.artifactId
+ : this.artifactId;
+ dependency.version = mapping.version != null ? mapping.version
+ : this.version;
+ dependency.versionRequirement = mapping.range.toString();
+ dependency.mappings = null;
+ return dependency;
+ }
+ }
+ return this;
+ }
+
+ /**
+ * Specify if this dependency is available for the specified Spring Boot version.
+ */
+ public boolean match(Version version) {
+ if (range!=null) {
+ return range.match(version);
+ }
+ return true;
+ }
+
+ /**
+ * Generate an id using the groupId and artifactId
+ */
+ public String generateId() {
+ if (groupId == null || artifactId == null) {
+ throw new IllegalArgumentException("Could not generate id for " + this
+ + ": at least groupId and artifactId must be set.");
+ }
+ StringBuilder sb = new StringBuilder();
+ sb.append(groupId).append(":").append(artifactId);
+ setId(sb.toString());
+ return getId();
+ }
+
+ public List getAliases() {
+ return aliases;
+ }
+
+ public void setAliases(List aliases) {
+ this.aliases = aliases;
+ }
+
+ public List getFacets() {
+ return facets;
+ }
+
+ public void setFacets(List facets) {
+ this.facets = facets;
+ }
+
+ public String getGroupId() {
+ return groupId;
+ }
+
+ public void setGroupId(String groupId) {
+ this.groupId = groupId;
+ }
+
+ public String getArtifactId() {
+ return artifactId;
+ }
+
+ public void setArtifactId(String artifactId) {
+ this.artifactId = artifactId;
+ }
+
+ public String getVersion() {
+ return version;
+ }
+
+ public void setVersion(String version) {
+ this.version = version;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public List getMappings() {
+ return mappings;
+ }
+
+ public void setMappings(List mappings) {
+ this.mappings = mappings;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public String getVersionRequirement() {
+ return versionRequirement;
+ }
+
+ public void setVersionRequirement(String versionRequirement) {
+ this.versionRequirement = versionRequirement;
+ }
+
+ public VersionRange getRange() {
+ return range;
+ }
+
+ public void setRange(VersionRange range) {
+ this.range = range;
+ }
+
+ public String getBom() {
+ return bom;
+ }
+
+ public void setBom(String bom) {
+ this.bom = bom;
+ }
+
+ public String getRepository() {
+ return repository;
+ }
+
+ public void setRepository(String repository) {
+ this.repository = repository;
+ }
+
+ public int getWeight() {
+ return weight;
+ }
+
+ public void setWeight(int weight) {
+ this.weight = weight;
+ }
+
+ public boolean isStarter() {
+ return starter;
+ }
+
+ public void setStarter(boolean starter) {
+ this.starter = starter;
+ }
+
+ public List getKeywords() {
+ return keywords;
+ }
+
+ public void setKeywords(List keywords) {
+ this.keywords = keywords;
+ }
+
+ public List getLinks() {
+ return links;
+ }
+
+ public void setLinks(List links) {
+ this.links = links;
+ }
+
+ public String getScope() {
+ return scope;
+ }
+
+ public String getVersionRange() {
+ return versionRange;
+ }
+
+ /**
+ * Map several attribute of the dependency for a given version range.
+ */
+ public static class Mapping {
+
+ /**
+ * The version range of this mapping.
+ */
+ private String versionRange;
+
+ /**
+ * The version to use for this mapping or {@code null} to use the default.
+ */
+ private String groupId;
+
+ /**
+ * The groupId to use for this mapping or {@code null} to use the default.
+ */
+ private String artifactId;
+
+ /**
+ * The artifactId to use for this mapping or {@code null} to use the default.
+ */
+ private String version;
+
+ private VersionRange range;
+
+ public String getGroupId() {
+ return groupId;
+ }
+
+ public void setGroupId(String groupId) {
+ this.groupId = groupId;
+ }
+
+ public String getArtifactId() {
+ return artifactId;
+ }
+
+ public void setArtifactId(String artifactId) {
+ this.artifactId = artifactId;
+ }
+
+ public String getVersion() {
+ return version;
+ }
+
+ public void setVersion(String version) {
+ this.version = version;
+ }
+
+ public VersionRange getRange() {
+ return range;
+ }
+
+ public String getVersionRange() {
+ return versionRange;
+ }
+
+ public void setVersionRange(String versionRange) {
+ this.versionRange = versionRange;
+ }
+
+ public static Mapping create(String range, String groupId, String artifactId,
+ String version) {
+ Mapping mapping = new Mapping();
+ mapping.versionRange = range;
+ mapping.groupId = groupId;
+ mapping.artifactId = artifactId;
+ mapping.version = version;
+ return mapping;
+ }
+ }
+
+ public static Dependency create(String groupId, String artifactId, String version,
+ String scope) {
+ Dependency dependency = withId(null, groupId, artifactId, version);
+ dependency.setScope(scope);
+ return dependency;
+ }
+
+ public static Dependency withId(String id, String groupId, String artifactId,
+ String version) {
+ Dependency dependency = new Dependency();
+ dependency.setId(id);
+ dependency.groupId = groupId;
+ dependency.artifactId = artifactId;
+ dependency.version = version;
+ return dependency;
+ }
+
+ public static Dependency withId(String id, String groupId, String artifactId) {
+ return withId(id, groupId, artifactId, null);
+ }
+
+ public static Dependency withId(String id, String scope) {
+ Dependency dependency = withId(id, null, null);
+ dependency.setScope(scope);
+ return dependency;
+ }
+
+ public static Dependency withId(String id) {
+ return withId(id, SCOPE_COMPILE);
+ }
+
+}
diff --git a/initializr-generator/src/main/groovy/io/spring/initializr/metadata/DependencyGroup.groovy b/initializr-generator/src/main/java/io/spring/initializr/metadata/DependencyGroup.java
similarity index 52%
rename from initializr-generator/src/main/groovy/io/spring/initializr/metadata/DependencyGroup.groovy
rename to initializr-generator/src/main/java/io/spring/initializr/metadata/DependencyGroup.java
index b623b718..4747d252 100644
--- a/initializr-generator/src/main/groovy/io/spring/initializr/metadata/DependencyGroup.groovy
+++ b/initializr-generator/src/main/java/io/spring/initializr/metadata/DependencyGroup.java
@@ -14,43 +14,88 @@
* limitations under the License.
*/
-package io.spring.initializr.metadata
+package io.spring.initializr.metadata;
-import com.fasterxml.jackson.annotation.JsonIgnore
+import java.util.ArrayList;
+import java.util.List;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
/**
* A group of {@link Dependency} instances identified by a name.
*
* @author Stephane Nicoll
*/
-class DependencyGroup {
+public class DependencyGroup {
/**
* Name of this group.
*/
- String name
+ private String name;
/**
* The default version range to apply to all dependencies of this group unless
* specified otherwise.
*/
@JsonIgnore
- String versionRange
+ private String versionRange;
/**
* The default bom to associate to all dependencies of this group unless
* specified otherwise.
*/
@JsonIgnore
- String bom
+ private String bom;
/**
* The default repository to associate to all dependencies of this group unless
* specified otherwise.
*/
@JsonIgnore
- String repository
+ private String repository;
- final List content = []
+ final List content = new ArrayList<>();
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getVersionRange() {
+ return versionRange;
+ }
+
+ public void setVersionRange(String versionRange) {
+ this.versionRange = versionRange;
+ }
+
+ public String getBom() {
+ return bom;
+ }
+
+ public void setBom(String bom) {
+ this.bom = bom;
+ }
+
+ public String getRepository() {
+ return repository;
+ }
+
+ public void setRepository(String repository) {
+ this.repository = repository;
+ }
+
+ public List getContent() {
+ return content;
+ }
+
+ public static DependencyGroup create(String name) {
+ DependencyGroup group = new DependencyGroup();
+ group.setName(name);
+ return group;
+ }
}
diff --git a/initializr-generator/src/main/java/io/spring/initializr/metadata/DependencyMetadata.java b/initializr-generator/src/main/java/io/spring/initializr/metadata/DependencyMetadata.java
new file mode 100644
index 00000000..dd31417a
--- /dev/null
+++ b/initializr-generator/src/main/java/io/spring/initializr/metadata/DependencyMetadata.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2012-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.
+ * You may obtain a copy of the License at
+ *
+ * http://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.metadata;
+
+import java.util.Map;
+
+import io.spring.initializr.util.Version;
+
+/**
+ * Dependency metadata for a given spring boot {@link Version}.
+ *
+ * @author Stephane Nicoll
+ */
+public class DependencyMetadata {
+
+ final Version bootVersion;
+
+ final Map dependencies;
+
+ final Map repositories;
+
+ final Map boms;
+
+ public DependencyMetadata() {
+ this(null, null, null, null);
+ }
+
+ public DependencyMetadata(Version bootVersion, Map dependencies,
+ Map repositories, Map boms) {
+ this.bootVersion = bootVersion;
+ this.dependencies = dependencies;
+ this.repositories = repositories;
+ this.boms = boms;
+ }
+
+ public Version getBootVersion() {
+ return bootVersion;
+ }
+
+ public Map getDependencies() {
+ return dependencies;
+ }
+
+ public Map getRepositories() {
+ return repositories;
+ }
+
+ public Map getBoms() {
+ return boms;
+ }
+
+}
diff --git a/initializr-generator/src/main/groovy/io/spring/initializr/metadata/DependencyMetadataProvider.groovy b/initializr-generator/src/main/java/io/spring/initializr/metadata/DependencyMetadataProvider.java
similarity index 86%
rename from initializr-generator/src/main/groovy/io/spring/initializr/metadata/DependencyMetadataProvider.groovy
rename to initializr-generator/src/main/java/io/spring/initializr/metadata/DependencyMetadataProvider.java
index 50b57ae2..3c7a7468 100644
--- a/initializr-generator/src/main/groovy/io/spring/initializr/metadata/DependencyMetadataProvider.groovy
+++ b/initializr-generator/src/main/java/io/spring/initializr/metadata/DependencyMetadataProvider.java
@@ -14,20 +14,20 @@
* limitations under the License.
*/
-package io.spring.initializr.metadata
+package io.spring.initializr.metadata;
-import io.spring.initializr.util.Version
+import io.spring.initializr.util.Version;
/**
* Provide the {@link DependencyMetadata} for a given spring boot version.
*
* @author Stephane Nicoll
*/
-interface DependencyMetadataProvider {
+public interface DependencyMetadataProvider {
/**
* Return the dependency metadata to use for the specified {@code bootVersion}.
*/
- DependencyMetadata get(InitializrMetadata metadata, Version bootVersion)
+ DependencyMetadata get(InitializrMetadata metadata, Version bootVersion);
}
\ No newline at end of file
diff --git a/initializr-generator/src/main/groovy/io/spring/initializr/metadata/Describable.groovy b/initializr-generator/src/main/java/io/spring/initializr/metadata/Describable.java
similarity index 95%
rename from initializr-generator/src/main/groovy/io/spring/initializr/metadata/Describable.groovy
rename to initializr-generator/src/main/java/io/spring/initializr/metadata/Describable.java
index ea0a89e2..98d822c4 100644
--- a/initializr-generator/src/main/groovy/io/spring/initializr/metadata/Describable.groovy
+++ b/initializr-generator/src/main/java/io/spring/initializr/metadata/Describable.java
@@ -16,6 +16,6 @@
package io.spring.initializr.metadata;
-interface Describable {
+public interface Describable {
String getDescription();
}
diff --git a/initializr-generator/src/main/java/io/spring/initializr/metadata/InitializrConfiguration.java b/initializr-generator/src/main/java/io/spring/initializr/metadata/InitializrConfiguration.java
new file mode 100644
index 00000000..829639c2
--- /dev/null
+++ b/initializr-generator/src/main/java/io/spring/initializr/metadata/InitializrConfiguration.java
@@ -0,0 +1,478 @@
+/*
+ * Copyright 2012-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.
+ * You may obtain a copy of the License at
+ *
+ * http://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.metadata;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import org.springframework.util.StringUtils;
+
+/**
+ * Various configuration options used by the service.
+ *
+ * @author Stephane Nicoll
+ */
+public class InitializrConfiguration {
+
+ /**
+ * Environment options.
+ */
+ private final Env env = new Env();
+
+ public Env getEnv() {
+ return env;
+ }
+
+ public void validate() {
+ env.validate();
+ }
+
+ public void merge(InitializrConfiguration other) {
+ env.merge(other.env);
+ }
+
+ /**
+ * Generate a suitable application name based on the specified name. If no suitable
+ * application name can be generated from the specified {@code name}, the
+ * {@link Env#fallbackApplicationName} is used instead.
+ *
+ * No suitable application name can be generated if the name is {@code null} or if it
+ * contains an invalid character for a class identifier.
+ * @see Env#fallbackApplicationName
+ * @see Env#invalidApplicationNames
+ */
+ public String generateApplicationName(String name) {
+ if (!StringUtils.hasText(name)) {
+ return env.fallbackApplicationName;
+ }
+ String text = splitCamelCase(name.trim());
+ // TODO: fix this
+ String result = unsplitWords(text);
+ if (!result.endsWith("Application")) {
+ result = result + "Application";
+ }
+ String candidate = StringUtils.capitalize(result);
+ if (hasInvalidChar(candidate)
+ || env.invalidApplicationNames.contains(candidate)) {
+ return env.fallbackApplicationName;
+ }
+ else {
+ return candidate;
+ }
+ }
+
+ /**
+ * Clean the specified package name if necessary. If the package name cannot be
+ * transformed to a valid package name, the {@code defaultPackageName} is used
+ * instead.
+ *
+ * The package name cannot be cleaned if the specified {@code packageName} is
+ * {@code null} or if it contains an invalid character for a class identifier.
+ * @see Env#invalidPackageNames
+ */
+ public String cleanPackageName(String packageName, String defaultPackageName) {
+ if (!StringUtils.hasText(packageName)) {
+ return defaultPackageName;
+ }
+ String candidate = String.join(".", packageName.trim().split("\\W+"));
+ if (hasInvalidChar(candidate.replace(".", ""))
+ || env.invalidPackageNames.contains(candidate)) {
+ return defaultPackageName;
+ }
+ else {
+ return candidate;
+ }
+ }
+
+ private static String unsplitWords(String text) {
+ return String
+ .join("", Arrays
+ .asList(text
+ .split("(_|-| |:)+"))
+ .stream().map(it -> StringUtils.capitalize(it))
+ .collect(Collectors.toList()).toArray(new String[0]));
+ }
+
+ private static String splitCamelCase(String text) {
+ return String
+ .join("", Arrays
+ .asList(text
+ .split("(? StringUtils.capitalize(it.toLowerCase()))
+ .collect(Collectors.toList()).toArray(new String[0]));
+ }
+
+ private static boolean hasInvalidChar(String text) {
+ if (!Character.isJavaIdentifierStart(text.charAt(0))) {
+ return true;
+ }
+ if (text.length() > 1) {
+ for (int i = 1; i < text.length(); i++) {
+ if (!Character.isJavaIdentifierPart(text.charAt(i))) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Defines additional environment settings.
+ */
+ public static class Env {
+
+ /**
+ * The url of the repository servicing distribution bundle.
+ */
+ private String artifactRepository = "https://repo.spring.io/release/";
+
+ /**
+ * The metadata url of the Spring Boot project.
+ */
+ private String springBootMetadataUrl = "https://spring.io/project_metadata/spring-boot";
+
+ /**
+ * Tracking code for Google Analytics. Only enabled if a value is explicitly
+ * provided.
+ */
+ private String googleAnalyticsTrackingCode;
+
+ /**
+ * The application name to use if none could be generated.
+ */
+ private String fallbackApplicationName = "Application";
+
+ /**
+ * The list of invalid application names. If such name is chosen or generated, the
+ * "fallbackApplicationName" should be used instead.
+ */
+ private List invalidApplicationNames = new ArrayList<>(
+ Arrays.asList("SpringApplication", "SpringBootApplication"));
+
+ /**
+ * The list of invalid package names. If such name is chosen or generated, the the
+ * default package name should be used instead.
+ */
+ private List invalidPackageNames = new ArrayList<>(
+ Arrays.asList("org.springframework"));
+
+ /**
+ * Force SSL support. When enabled, any access using http generate https links.
+ */
+ private boolean forceSsl = true;
+
+ /**
+ * The "BillOfMaterials" that are referenced in this instance, identified by an
+ * arbitrary identifier that can be used in the dependencies definition.
+ */
+ private final Map boms = new LinkedHashMap<>();
+
+ /**
+ * The "Repository" instances that are referenced in this instance, identified by
+ * an arbitrary identifier that can be used in the dependencies definition.
+ */
+ private final Map repositories = new LinkedHashMap<>();
+
+ /**
+ * Gradle-specific settings.
+ */
+ private final Gradle gradle = new Gradle();
+
+ /**
+ * Kotlin-specific settings.
+ */
+ private final Kotlin kotlin = new Kotlin();
+
+ /**
+ * Maven-specific settings.
+ */
+ private final Maven maven = new Maven();
+
+ public String getSpringBootMetadataUrl() {
+ return springBootMetadataUrl;
+ }
+
+ public void setSpringBootMetadataUrl(String springBootMetadataUrl) {
+ this.springBootMetadataUrl = springBootMetadataUrl;
+ }
+
+ public String getGoogleAnalyticsTrackingCode() {
+ return googleAnalyticsTrackingCode;
+ }
+
+ public void setGoogleAnalyticsTrackingCode(String googleAnalyticsTrackingCode) {
+ this.googleAnalyticsTrackingCode = googleAnalyticsTrackingCode;
+ }
+
+ public String getFallbackApplicationName() {
+ return fallbackApplicationName;
+ }
+
+ public void setFallbackApplicationName(String fallbackApplicationName) {
+ this.fallbackApplicationName = fallbackApplicationName;
+ }
+
+ public List getInvalidApplicationNames() {
+ return invalidApplicationNames;
+ }
+
+ public void setInvalidApplicationNames(List invalidApplicationNames) {
+ this.invalidApplicationNames = invalidApplicationNames;
+ }
+
+ public List getInvalidPackageNames() {
+ return invalidPackageNames;
+ }
+
+ public void setInvalidPackageNames(List invalidPackageNames) {
+ this.invalidPackageNames = invalidPackageNames;
+ }
+
+ public boolean isForceSsl() {
+ return forceSsl;
+ }
+
+ public void setForceSsl(boolean forceSsl) {
+ this.forceSsl = forceSsl;
+ }
+
+ public String getArtifactRepository() {
+ return artifactRepository;
+ }
+
+ public Map getBoms() {
+ return boms;
+ }
+
+ public Map getRepositories() {
+ return repositories;
+ }
+
+ public Gradle getGradle() {
+ return gradle;
+ }
+
+ public Kotlin getKotlin() {
+ return kotlin;
+ }
+
+ public Maven getMaven() {
+ return maven;
+ }
+
+ public Env() {
+ try {
+ repositories.put("spring-snapshots", new Repository("Spring Snapshots",
+ new URL("https://repo.spring.io/snapshot"), true));
+ repositories.put("spring-milestones", new Repository("Spring Milestones",
+ new URL("https://repo.spring.io/milestone"), false));
+ }
+ catch (MalformedURLException e) {
+ throw new IllegalStateException("Cannot parse URL", e);
+ }
+ }
+
+ public void setArtifactRepository(String artifactRepository) {
+ if (!artifactRepository.endsWith("/")) {
+ artifactRepository = artifactRepository + "/";
+ }
+ this.artifactRepository = artifactRepository;
+ }
+
+ public void validate() {
+ maven.parent.validate();
+ boms.forEach((k, v) -> {
+ v.validate();
+ });
+ }
+
+ public void merge(Env other) {
+ artifactRepository = other.artifactRepository;
+ springBootMetadataUrl = other.springBootMetadataUrl;
+ googleAnalyticsTrackingCode = other.googleAnalyticsTrackingCode;
+ fallbackApplicationName = other.fallbackApplicationName;
+ invalidApplicationNames = other.invalidApplicationNames;
+ forceSsl = other.forceSsl;
+ gradle.merge(other.gradle);
+ kotlin.version = other.kotlin.version;
+ maven.merge(other.maven);
+ other.boms.forEach((id, bom) -> {
+ if (boms.get(id) == null) {
+ boms.put(id, bom);
+ }
+ });
+ other.repositories.forEach((id, repo) -> {
+ if (repositories.get(id) == null) {
+ repositories.put(id, repo);
+ }
+ });
+ }
+
+ public static class Gradle {
+
+ /**
+ * Version of the "dependency-management-plugin" to use.
+ */
+ private String dependencyManagementPluginVersion;
+
+ private void merge(Gradle other) {
+ dependencyManagementPluginVersion = other.dependencyManagementPluginVersion;
+ }
+
+ public String getDependencyManagementPluginVersion() {
+ return dependencyManagementPluginVersion;
+ }
+
+ public void setDependencyManagementPluginVersion(
+ String dependencyManagementPluginVersion) {
+ this.dependencyManagementPluginVersion = dependencyManagementPluginVersion;
+ }
+
+ }
+
+ public static class Kotlin {
+
+ /**
+ * Kotlin version to use.
+ */
+ private String version;
+
+ public String getVersion() {
+ return version;
+ }
+
+ public void setVersion(String version) {
+ this.version = version;
+ }
+ }
+
+ public static class Maven {
+
+ /**
+ * Custom parent pom to use for generated projects.
+ */
+ private final ParentPom parent = new ParentPom();
+
+ public ParentPom getParent() {
+ return parent;
+ }
+
+ private void merge(Maven other) {
+ parent.groupId = other.parent.groupId;
+ parent.artifactId = other.parent.artifactId;
+ parent.version = other.parent.version;
+ parent.includeSpringBootBom = other.parent.includeSpringBootBom;
+ }
+
+ /**
+ * Resolve the parent pom to use. If no custom parent pom is set, the standard
+ * spring boot parent pom with the specified {@code bootVersion} is used.
+ */
+ public ParentPom resolveParentPom(String bootVersion) {
+ return StringUtils.hasText(parent.groupId) ? parent
+ : new ParentPom("org.springframework.boot",
+ "spring-boot-starter-parent", bootVersion);
+ }
+
+ public static class ParentPom {
+
+ /**
+ * Parent pom groupId.
+ */
+ private String groupId;
+
+ /**
+ * Parent pom artifactId.
+ */
+ private String artifactId;
+
+ /**
+ * Parent pom version.
+ */
+ private String version;
+
+ /**
+ * Add the "spring-boot-dependencies" BOM to the project.
+ */
+ private boolean includeSpringBootBom;
+
+ public ParentPom(String groupId, String artifactId, String version) {
+ this.groupId = groupId;
+ this.artifactId = artifactId;
+ this.version = version;
+ }
+
+ public ParentPom() {
+ }
+
+ public String getGroupId() {
+ return groupId;
+ }
+
+ public void setGroupId(String groupId) {
+ this.groupId = groupId;
+ }
+
+ public String getArtifactId() {
+ return artifactId;
+ }
+
+ public void setArtifactId(String artifactId) {
+ this.artifactId = artifactId;
+ }
+
+ public String getVersion() {
+ return version;
+ }
+
+ public void setVersion(String version) {
+ this.version = version;
+ }
+
+ public boolean isIncludeSpringBootBom() {
+ return includeSpringBootBom;
+ }
+
+ public void setIncludeSpringBootBom(boolean includeSpringBootBom) {
+ this.includeSpringBootBom = includeSpringBootBom;
+ }
+
+ public void validate() {
+ if (!((!StringUtils.hasText(groupId)
+ && !StringUtils.hasText(artifactId)
+ && !StringUtils.hasText(version))
+ || (StringUtils.hasText(groupId)
+ && StringUtils.hasText(artifactId)
+ && StringUtils.hasText(version)))) {
+ throw new InvalidInitializrMetadataException("Custom maven pom "
+ + "requires groupId, artifactId and version");
+ }
+ }
+
+ }
+
+ }
+
+ }
+
+}
diff --git a/initializr-generator/src/main/java/io/spring/initializr/metadata/InitializrMetadata.java b/initializr-generator/src/main/java/io/spring/initializr/metadata/InitializrMetadata.java
new file mode 100644
index 00000000..e9e93a91
--- /dev/null
+++ b/initializr-generator/src/main/java/io/spring/initializr/metadata/InitializrMetadata.java
@@ -0,0 +1,300 @@
+/*
+ * Copyright 2012-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.
+ * You may obtain a copy of the License at
+ *
+ * http://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.metadata;
+
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import io.spring.initializr.util.Version;
+import io.spring.initializr.util.VersionParser;
+
+/**
+ * Meta-data used to generate a project.
+ *
+ * @author Stephane Nicoll
+ * @see ServiceCapability
+ */
+public class InitializrMetadata {
+
+ private final InitializrConfiguration configuration;
+
+ private final DependenciesCapability dependencies = new DependenciesCapability();
+
+ private final TypeCapability types = new TypeCapability();
+
+ private final SingleSelectCapability bootVersions = new SingleSelectCapability("bootVersion",
+ "Spring Boot Version", "spring boot version");
+
+ private final SingleSelectCapability packagings = new SingleSelectCapability("packaging",
+ "Packaging", "project packaging");
+
+ private final SingleSelectCapability javaVersions = new SingleSelectCapability("javaVersion",
+ "Java Version", "language level");
+
+ private final SingleSelectCapability languages = new SingleSelectCapability("language",
+ "Language", "programming language");
+
+ private final TextCapability name = new TextCapability("name", "Name",
+ "project name (infer application name)");
+
+ private final TextCapability description = new TextCapability("description", "Description",
+ "project description");
+
+ private final TextCapability groupId = new TextCapability("groupId", "Group",
+ "project coordinates");
+
+ private final TextCapability artifactId = new ArtifactIdCapability(name);
+
+ private final TextCapability version = new TextCapability("version", "Version",
+ "project version");
+
+ private final TextCapability packageName = new PackageCapability(groupId);
+
+ public InitializrMetadata() {
+ this(new InitializrConfiguration());
+ }
+
+ protected InitializrMetadata(InitializrConfiguration configuration) {
+ this.configuration = configuration;
+ }
+
+ public InitializrConfiguration getConfiguration() {
+ return configuration;
+ }
+
+ public DependenciesCapability getDependencies() {
+ return dependencies;
+ }
+
+ public TypeCapability getTypes() {
+ return types;
+ }
+
+ public SingleSelectCapability getBootVersions() {
+ return bootVersions;
+ }
+
+ public SingleSelectCapability getPackagings() {
+ return packagings;
+ }
+
+ public SingleSelectCapability getJavaVersions() {
+ return javaVersions;
+ }
+
+ public SingleSelectCapability getLanguages() {
+ return languages;
+ }
+
+ public TextCapability getName() {
+ return name;
+ }
+
+ public TextCapability getDescription() {
+ return description;
+ }
+
+ public TextCapability getGroupId() {
+ return groupId;
+ }
+
+ public TextCapability getArtifactId() {
+ return artifactId;
+ }
+
+ public TextCapability getVersion() {
+ return version;
+ }
+
+ public TextCapability getPackageName() {
+ return packageName;
+ }
+
+ /**
+ * Merge this instance with the specified argument
+ * @param other
+ */
+ public void merge(InitializrMetadata other) {
+ this.configuration.merge(other.configuration);
+ this.dependencies.merge(other.dependencies);
+ this.types.merge(other.types);
+ this.bootVersions.merge(other.bootVersions);
+ this.packagings.merge(other.packagings);
+ this.javaVersions.merge(other.javaVersions);
+ this.languages.merge(other.languages);
+ this.name.merge(other.name);
+ this.description.merge(other.description);
+ this.groupId.merge(other.groupId);
+ this.artifactId.merge(other.artifactId);
+ this.version.merge(other.version);
+ this.packageName.merge(other.packageName);
+ }
+
+ /**
+ * Validate the metadata.
+ */
+ public void validate() {
+ this.configuration.validate();
+ dependencies.validate();
+
+ Map repositories = configuration.getEnv().getRepositories();
+ Map boms = configuration.getEnv().getBoms();
+ for (Dependency dependency : dependencies.getAll()) {
+ if (dependency.getBom() != null && !boms.containsKey(dependency.getBom())) {
+ throw new InvalidInitializrMetadataException(
+ "Dependency " + dependency + "defines an invalid BOM id "
+ + dependency.getBom() + ", available boms " + boms);
+ }
+
+ if (dependency.getRepository() != null
+ && !repositories.containsKey(dependency.getRepository())) {
+ throw new InvalidInitializrMetadataException("Dependency " + dependency
+ + "defines an invalid repository id " + dependency.getRepository()
+ + ", available repositores " + repositories);
+ }
+ }
+ for (BillOfMaterials bom : boms.values()) {
+ for (String r : bom.getRepositories()) {
+ if (!repositories.containsKey(r)) {
+ throw new InvalidInitializrMetadataException(
+ bom + "defines an invalid repository id " + r
+ + ", available repositories " + repositories);
+ }
+ }
+ for (String b : bom.getAdditionalBoms()) {
+ if (!boms.containsKey(b)) {
+ throw new InvalidInitializrMetadataException(
+ bom + " defines an invalid " + "additional bom id " + b
+ + ", available boms " + boms);
+ }
+ }
+ for (BillOfMaterials.Mapping m : bom.getMappings()) {
+ for (String r : m.getRepositories()) {
+ if (!repositories.containsKey(r)) {
+ throw new InvalidInitializrMetadataException(
+ m + " of " + bom + "defines an invalid repository id " + r
+ + ", available repositores " + repositories);
+ }
+
+ }
+ for (String b : m.getAdditionalBoms()) {
+ if (!boms.containsKey(b)) {
+ throw new InvalidInitializrMetadataException(m + " of " + bom
+ + " defines " + "an invalid additional bom id " + b
+ + ", available boms " + boms);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Update the available Spring Boot versions with the specified capabilities.
+ * @param versionsMetadata the Spring Boot boot versions metadata to use
+ */
+ public void updateSpringBootVersions(List versionsMetadata) {
+ this.bootVersions.getContent().clear();
+ this.bootVersions.getContent().addAll(versionsMetadata);
+ List bootVersions = this.bootVersions.getContent().stream()
+ .map(it -> Version.parse(it.getId())).collect(Collectors.toList());
+ VersionParser parser = new VersionParser(bootVersions);
+ dependencies.updateVersionRange(parser);
+ configuration.getEnv().getBoms().values()
+ .forEach(it -> it.updateVersionRange(parser));
+ }
+
+ /**
+ * Create an URL suitable to download Spring Boot cli for the specified version and
+ * extension.
+ */
+ public String createCliDistributionURl(String extension) {
+ String bootVersion = defaultId(bootVersions);
+ return configuration.getEnv().getArtifactRepository()
+ + "org/springframework/boot/spring-boot-cli/" + bootVersion
+ + "/spring-boot-cli-" + bootVersion + "-bin." + extension;
+ }
+
+ /**
+ * Create a {@link BillOfMaterials} for the spring boot BOM.
+ */
+ public BillOfMaterials createSpringBootBom(String bootVersion, String versionProperty) {
+ BillOfMaterials bom = BillOfMaterials.create("org.springframework.boot",
+ "spring-boot-dependencies", bootVersion);
+ bom.setVersionProperty(versionProperty);
+ bom.setOrder(100);
+ return bom;
+ }
+
+ /**
+ * Return the defaults for the capabilities defined on this instance.
+ */
+ public Map defaults() {
+ Map defaults = new LinkedHashMap<>();
+ defaults.put("type", defaultId(types));
+ defaults.put("bootVersion", defaultId(bootVersions));
+ defaults.put("packaging", defaultId(packagings));
+ defaults.put("javaVersion", defaultId(javaVersions));
+ defaults.put("language", defaultId(languages));
+ defaults.put("groupId", groupId.getContent());
+ defaults.put("artifactId", artifactId.getContent());
+ defaults.put("version", version.getContent());
+ defaults.put("name", name.getContent());
+ defaults.put("description", description.getContent());
+ defaults.put("packageName", packageName.getContent());
+ return defaults;
+ }
+
+ private static String defaultId(Defaultable extends DefaultMetadataElement> element) {
+ DefaultMetadataElement defaultValue = element.getDefault();
+ return defaultValue != null ? defaultValue.getId() : null;
+ }
+
+ private static class ArtifactIdCapability extends TextCapability {
+ private final TextCapability nameCapability;
+
+ ArtifactIdCapability(TextCapability nameCapability) {
+ super("artifactId", "Artifact", "project coordinates (infer archive name)");
+ this.nameCapability = nameCapability;
+ }
+
+ @Override
+ public String getContent() {
+ String value = super.getContent();
+ return value == null ? nameCapability.getContent() : value;
+ }
+ }
+
+ private static class PackageCapability extends TextCapability {
+ private final TextCapability nameCapability;
+
+ PackageCapability(TextCapability nameCapability) {
+ super("packageName", "Package Name", "root package");
+ this.nameCapability = nameCapability;
+ }
+
+ @Override
+ public String getContent() {
+ String value = super.getContent();
+ return value != null ? value
+ : (nameCapability.getContent() != null
+ ? nameCapability.getContent().replace("-", ".") : null);
+ }
+ }
+
+}
diff --git a/initializr-generator/src/main/java/io/spring/initializr/metadata/InitializrMetadataBuilder.java b/initializr-generator/src/main/java/io/spring/initializr/metadata/InitializrMetadataBuilder.java
new file mode 100644
index 00000000..ae90eca9
--- /dev/null
+++ b/initializr-generator/src/main/java/io/spring/initializr/metadata/InitializrMetadataBuilder.java
@@ -0,0 +1,205 @@
+/*
+ * Copyright 2012-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.
+ * You may obtain a copy of the License at
+ *
+ * http://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.metadata;
+
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.core.io.Resource;
+import org.springframework.util.StreamUtils;
+import org.springframework.util.StringUtils;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+/**
+ * Builder for {@link InitializrMetadata}. Allows to read metadata from any arbitrary
+ * resource, including remote URLs.
+ *
+ * @author Stephane Nicoll
+ * @see InitializrMetadataCustomizer
+ */
+public class InitializrMetadataBuilder {
+
+ private final List customizers = new ArrayList<>();
+ private final InitializrConfiguration configuration;
+
+ private InitializrMetadataBuilder(InitializrConfiguration configuration) {
+ this.configuration = configuration;
+ }
+
+ /**
+ * Create a builder instance from the specified {@link InitializrProperties}.
+ * Initialize the configuration to use.
+ * @see #withInitializrProperties(InitializrProperties)
+ */
+ public static InitializrMetadataBuilder fromInitializrProperties(
+ InitializrProperties configuration) {
+ return new InitializrMetadataBuilder(configuration)
+ .withInitializrProperties(configuration);
+ }
+
+ /**
+ * Create an empty builder instance with a default {@link InitializrConfiguration}
+ */
+ public static InitializrMetadataBuilder create() {
+ return new InitializrMetadataBuilder(new InitializrConfiguration());
+ }
+
+ /**
+ * Add a {@link InitializrProperties} to be merged with other content. Merges the
+ * settings only and not the configuration.
+ * @see #withInitializrProperties(InitializrProperties, boolean)
+ */
+ public InitializrMetadataBuilder withInitializrProperties(
+ InitializrProperties properties) {
+ return withInitializrProperties(properties, false);
+ }
+
+ /**
+ * Add a {@link InitializrProperties} to be merged with other content.
+ * @param properties the settings to merge onto this instance
+ * @param mergeConfiguration specify if service configuration should be merged as well
+ */
+ public InitializrMetadataBuilder withInitializrProperties(
+ InitializrProperties properties, boolean mergeConfiguration) {
+ if (mergeConfiguration) {
+ this.configuration.merge(properties);
+ }
+ return withCustomizer(new InitializerPropertiesCustomizer(properties));
+ }
+
+ /**
+ * Add a {@link InitializrMetadata} to be merged with other content.
+ * @param resource a resource to a json document describing the metadata to include
+ */
+ public InitializrMetadataBuilder withInitializrMetadata(Resource resource) {
+ return withCustomizer(new ResourceInitializrMetadataCustomizer(resource));
+ }
+
+ /**
+ * Add a {@link InitializrMetadataCustomizer}. customizers are invoked in their order
+ * of addition.
+ * @see InitializrMetadataCustomizer
+ */
+ public InitializrMetadataBuilder withCustomizer(
+ InitializrMetadataCustomizer customizer) {
+ customizers.add(customizer);
+ return this;
+ }
+
+ /**
+ * Build a {@link InitializrMetadata} based on the state of this builder.
+ */
+ public InitializrMetadata build() {
+ InitializrConfiguration config = this.configuration != null ? this.configuration
+ : new InitializrConfiguration();
+ InitializrMetadata metadata = createInstance(config);
+ for (InitializrMetadataCustomizer customizer : customizers) {
+ customizer.customize(metadata);
+ }
+ applyDefaults(metadata);
+ metadata.validate();
+ return metadata;
+ }
+
+ /**
+ * Creates an empty instance based on the specified {@link InitializrConfiguration}
+ */
+ protected InitializrMetadata createInstance(InitializrConfiguration configuration) {
+ return new InitializrMetadata(configuration);
+ }
+
+ /**
+ * Apply defaults to capabilities that have no value.
+ */
+ protected void applyDefaults(InitializrMetadata metadata) {
+ if (!StringUtils.hasText(metadata.getName().getContent())) {
+ metadata.getName().setContent("demo");
+ }
+ if (!StringUtils.hasText(metadata.getDescription().getContent())) {
+ metadata.getDescription().setContent("Demo project for Spring Boot");
+ }
+ if (!StringUtils.hasText(metadata.getGroupId().getContent())) {
+ metadata.getGroupId().setContent("com.example");
+ }
+ if (!StringUtils.hasText(metadata.getVersion().getContent())) {
+ metadata.getVersion().setContent("0.0.1-SNAPSHOT");
+ }
+ }
+
+ private static class InitializerPropertiesCustomizer
+ implements InitializrMetadataCustomizer {
+
+ private final InitializrProperties properties;
+
+ InitializerPropertiesCustomizer(InitializrProperties properties) {
+ this.properties = properties;
+ }
+
+ @Override
+ public void customize(InitializrMetadata metadata) {
+ metadata.getDependencies().merge(properties.getDependencies());
+ metadata.getTypes().merge(properties.getTypes());
+ metadata.getBootVersions().merge(properties.getBootVersions());
+ metadata.getPackagings().merge(properties.getPackagings());
+ metadata.getJavaVersions().merge(properties.getJavaVersions());
+ metadata.getLanguages().merge(properties.getLanguages());
+ properties.getGroupId().apply(metadata.getGroupId());
+ properties.getArtifactId().apply(metadata.getArtifactId());
+ properties.getVersion().apply(metadata.getVersion());
+ properties.getName().apply(metadata.getName());
+ properties.getDescription().apply(metadata.getDescription());
+ properties.getPackageName().apply(metadata.getPackageName());
+ }
+ }
+
+ private static class ResourceInitializrMetadataCustomizer
+ implements InitializrMetadataCustomizer {
+
+ private static final Logger log = LoggerFactory.getLogger(
+ InitializrMetadataBuilder.ResourceInitializrMetadataCustomizer.class);
+
+ private static final Charset UTF_8 = Charset.forName("UTF-8");
+
+ private final Resource resource;
+
+ ResourceInitializrMetadataCustomizer(Resource resource) {
+ this.resource = resource;
+ }
+
+ @Override
+ public void customize(InitializrMetadata metadata) {
+ log.info("Loading initializr metadata from " + resource);
+ try {
+ String content = StreamUtils.copyToString(resource.getInputStream(),
+ UTF_8);
+ ObjectMapper objectMapper = new ObjectMapper();
+ InitializrMetadata anotherMetadata = objectMapper.readValue(content,
+ InitializrMetadata.class);
+ metadata.merge(anotherMetadata);
+ }
+ catch (Exception e) {
+ throw new IllegalStateException("Cannot merge", e);
+ }
+ }
+
+ }
+
+}
diff --git a/initializr-generator/src/main/groovy/io/spring/initializr/metadata/InitializrMetadataCustomizer.groovy b/initializr-generator/src/main/java/io/spring/initializr/metadata/InitializrMetadataCustomizer.java
similarity index 86%
rename from initializr-generator/src/main/groovy/io/spring/initializr/metadata/InitializrMetadataCustomizer.groovy
rename to initializr-generator/src/main/java/io/spring/initializr/metadata/InitializrMetadataCustomizer.java
index 36292e75..4edb9956 100644
--- a/initializr-generator/src/main/groovy/io/spring/initializr/metadata/InitializrMetadataCustomizer.groovy
+++ b/initializr-generator/src/main/java/io/spring/initializr/metadata/InitializrMetadataCustomizer.java
@@ -14,19 +14,19 @@
* limitations under the License.
*/
-package io.spring.initializr.metadata
+package io.spring.initializr.metadata;
/**
* Strategy interface used to customize the {@link InitializrMetadata}.
*
* @author Dave Syer
*/
-interface InitializrMetadataCustomizer {
+public interface InitializrMetadataCustomizer {
/**
* Customize the {@link InitializrMetadata}, updating or moving around
* capabilities before they are validated.
*/
- void customize(InitializrMetadata metadata)
+ void customize(InitializrMetadata metadata);
}
diff --git a/initializr-generator/src/main/groovy/io/spring/initializr/metadata/InitializrMetadataProvider.groovy b/initializr-generator/src/main/java/io/spring/initializr/metadata/InitializrMetadataProvider.java
similarity index 88%
rename from initializr-generator/src/main/groovy/io/spring/initializr/metadata/InitializrMetadataProvider.groovy
rename to initializr-generator/src/main/java/io/spring/initializr/metadata/InitializrMetadataProvider.java
index 3db8ceee..32a87dda 100644
--- a/initializr-generator/src/main/groovy/io/spring/initializr/metadata/InitializrMetadataProvider.groovy
+++ b/initializr-generator/src/main/java/io/spring/initializr/metadata/InitializrMetadataProvider.java
@@ -14,20 +14,20 @@
* limitations under the License.
*/
-package io.spring.initializr.metadata
+package io.spring.initializr.metadata;
/**
* Provide the {@link InitializrMetadata} to use.
*
* @author Stephane Nicoll
*/
-interface InitializrMetadataProvider {
+public interface InitializrMetadataProvider {
/**
* Return the metadata to use. Rather than keeping a handle to
* a particular instance, implementations may decide to refresh
* or recompute the metadata if necessary.
*/
- InitializrMetadata get()
+ InitializrMetadata get();
}
\ No newline at end of file
diff --git a/initializr-generator/src/main/java/io/spring/initializr/metadata/InitializrProperties.java b/initializr-generator/src/main/java/io/spring/initializr/metadata/InitializrProperties.java
new file mode 100644
index 00000000..d058e639
--- /dev/null
+++ b/initializr-generator/src/main/java/io/spring/initializr/metadata/InitializrProperties.java
@@ -0,0 +1,213 @@
+/*
+ * Copyright 2012-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.
+ * You may obtain a copy of the License at
+ *
+ * http://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.metadata;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.util.StringUtils;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+
+/**
+ * Configuration of the initializr service.
+ *
+ * @author Stephane Nicoll
+ */
+@ConfigurationProperties(prefix = "initializr")
+public class InitializrProperties extends InitializrConfiguration {
+
+ /**
+ * Dependencies, organized in groups (i.e. themes).
+ */
+ @JsonIgnore
+ private final List dependencies = new ArrayList<>();
+
+ /**
+ * Available project types.
+ */
+ @JsonIgnore
+ private final List types = new ArrayList<>();
+
+ /**
+ * Available packaging types.
+ */
+ @JsonIgnore
+ private final List packagings = new ArrayList<>();
+
+ /**
+ * Available java versions.
+ */
+ @JsonIgnore
+ private final List javaVersions = new ArrayList<>();
+
+ /**
+ * Available programming languages.
+ */
+ @JsonIgnore
+ private final List languages = new ArrayList<>();
+
+ /**
+ * Available Spring Boot versions.
+ */
+ @JsonIgnore
+ private final List bootVersions = new ArrayList<>();
+
+ /**
+ * GroupId metadata.
+ */
+ @JsonIgnore
+ private final SimpleElement groupId = new SimpleElement("com.example");
+
+ /**
+ * ArtifactId metadata.
+ */
+ @JsonIgnore
+ private final SimpleElement artifactId = new SimpleElement(null);
+
+ /**
+ * Version metadata.
+ */
+ @JsonIgnore
+ private final SimpleElement version = new SimpleElement("0.0.1-SNAPSHOT");
+
+ /**
+ * Name metadata.
+ */
+ @JsonIgnore
+ private final SimpleElement name = new SimpleElement("demo");
+
+ /**
+ * Description metadata.
+ */
+ @JsonIgnore
+ private final SimpleElement description = new SimpleElement(
+ "Demo project for Spring Boot");
+
+ /**
+ * Package name metadata.
+ */
+ @JsonIgnore
+ private final SimpleElement packageName = new SimpleElement(null);
+
+ public List getDependencies() {
+ return dependencies;
+ }
+
+ public List getTypes() {
+ return types;
+ }
+
+ public List getPackagings() {
+ return packagings;
+ }
+
+ public List getJavaVersions() {
+ return javaVersions;
+ }
+
+ public List getLanguages() {
+ return languages;
+ }
+
+ public List getBootVersions() {
+ return bootVersions;
+ }
+
+ public SimpleElement getGroupId() {
+ return groupId;
+ }
+
+ public SimpleElement getArtifactId() {
+ return artifactId;
+ }
+
+ public SimpleElement getVersion() {
+ return version;
+ }
+
+ public SimpleElement getName() {
+ return name;
+ }
+
+ public SimpleElement getDescription() {
+ return description;
+ }
+
+ public SimpleElement getPackageName() {
+ return packageName;
+ }
+
+ public static class SimpleElement {
+ /**
+ * Element title.
+ */
+ private String title;
+
+ /**
+ * Element description.
+ */
+ private String description;
+
+ /**
+ * Element default value.
+ */
+ private String value;
+
+ public SimpleElement(String value) {
+ this.value = value;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public void setValue(String value) {
+ this.value = value;
+ }
+
+ public void apply(TextCapability capability) {
+ if (StringUtils.hasText(title)) {
+ capability.setTitle(title);
+ }
+ if (StringUtils.hasText(description)) {
+ capability.setDescription(description);
+ }
+ if (StringUtils.hasText(value)) {
+ capability.setContent(value);
+ }
+ }
+ }
+
+}
diff --git a/initializr-generator/src/main/groovy/io/spring/initializr/metadata/DefaultMetadataElement.groovy b/initializr-generator/src/main/java/io/spring/initializr/metadata/InvalidInitializrMetadataException.java
similarity index 60%
rename from initializr-generator/src/main/groovy/io/spring/initializr/metadata/DefaultMetadataElement.groovy
rename to initializr-generator/src/main/java/io/spring/initializr/metadata/InvalidInitializrMetadataException.java
index 8819070f..2572f053 100644
--- a/initializr-generator/src/main/groovy/io/spring/initializr/metadata/DefaultMetadataElement.groovy
+++ b/initializr-generator/src/main/java/io/spring/initializr/metadata/InvalidInitializrMetadataException.java
@@ -14,23 +14,23 @@
* limitations under the License.
*/
-package io.spring.initializr.metadata
+package io.spring.initializr.metadata;
+
+import io.spring.initializr.InitializrException;
/**
- * A {@link MetadataElement} that specifies if its
- * the default for a given capability.
+ * Thrown when the configuration defines invalid metadata.
*
* @author Stephane Nicoll
*/
-class DefaultMetadataElement extends MetadataElement {
+@SuppressWarnings("serial")
+public class InvalidInitializrMetadataException extends InitializrException {
- private boolean defaultValue
-
- void setDefault(boolean defaultValue) {
- this.defaultValue = defaultValue
+ public InvalidInitializrMetadataException(String message, Throwable cause) {
+ super(message, cause);
}
- boolean isDefault() {
- this.defaultValue
+ public InvalidInitializrMetadataException(String message) {
+ super(message);
}
}
diff --git a/initializr-generator/src/main/java/io/spring/initializr/metadata/Link.java b/initializr-generator/src/main/java/io/spring/initializr/metadata/Link.java
new file mode 100644
index 00000000..c8749c22
--- /dev/null
+++ b/initializr-generator/src/main/java/io/spring/initializr/metadata/Link.java
@@ -0,0 +1,178 @@
+/*
+ * Copyright 2012-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.
+ * You may obtain a copy of the License at
+ *
+ * http://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.metadata;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonInclude;
+
+/**
+ * Metadata for a link. Each link has a "relation" that potentially attaches a strong
+ * semantic to the nature of the link. The URI of the link itself can be templated by
+ * including variables in the form `{variableName}`.
+ *
+ * An actual {@code URI} can be generated using {@code expand}, providing a mapping for
+ * those variables.
+ *
+ * @author Dave Syer
+ * @author Stephane Nicoll
+ */
+public class Link {
+
+ private static final Pattern VARIABLE_REGEX = Pattern.compile("\\{(\\w+)\\}");
+
+ /**
+ * The relation of the link.
+ */
+ private String rel;
+
+ /**
+ * The URI the link is pointing to.
+ */
+ private String href;
+
+ /**
+ * Specify if the URI is templated.
+ */
+ @JsonInclude(JsonInclude.Include.NON_DEFAULT)
+ private boolean templated;
+
+ @JsonIgnore
+ private final Set templateVariables = new LinkedHashSet<>();
+
+ /**
+ * A description of the link.
+ */
+ @JsonInclude(JsonInclude.Include.NON_NULL)
+ private String description;
+
+ public Link() {
+ }
+
+ private Link(String rel, String href) {
+ this(rel, href, (String)null);
+ }
+
+ private Link(String rel, String href, String description) {
+ this.rel = rel;
+ this.href = href;
+ this.description = description;
+ }
+
+ private Link(String rel, String href, boolean templated) {
+ this(rel, href);
+ this.templated = templated;
+ }
+
+ public String getRel() {
+ return rel;
+ }
+
+ public void setRel(String rel) {
+ this.rel = rel;
+ }
+
+ public boolean isTemplated() {
+ return templated;
+ }
+
+ public void setTemplated(boolean templated) {
+ this.templated = templated;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public String getHref() {
+ return href;
+ }
+
+ public Set getTemplateVariables() {
+ return Collections.unmodifiableSet(templateVariables);
+ }
+
+ public void setHref(String href) {
+ this.href = href;
+ }
+
+ public void resolve() {
+ if (rel==null) {
+ throw new InvalidInitializrMetadataException(
+ "Invalid link " + this + ": rel attribute is mandatory");
+ }
+ if (href==null) {
+ throw new InvalidInitializrMetadataException(
+ "Invalid link " + this + ": href attribute is mandatory");
+ }
+ Matcher matcher = VARIABLE_REGEX.matcher(href);
+ while (matcher.find()) {
+ String variable = matcher.group(1);
+ this.templateVariables.add(variable);
+ }
+ this.templated = !this.templateVariables.isEmpty();
+ }
+
+ /**
+ * Expand the link using the specified parameters.
+ * @param parameters the parameters value
+ * @return an URI where all variables have been expanded
+ */
+ public URI expand(Map parameters) {
+ AtomicReference result = new AtomicReference(href);
+ templateVariables.forEach( var -> {
+ Object value = parameters.get(var);
+ if (value==null) {
+ throw new IllegalArgumentException(
+ "Could not expand " + href + ", missing value for '" + var + "'");
+ }
+ result.set(result.get().replace("{" + var+"}", value.toString()));
+ });
+ try {
+ return new URI(result.get());
+ }
+ catch (URISyntaxException e) {
+ throw new IllegalStateException("Invalid URL", e);
+ }
+ }
+
+ public static Link create(String rel, String href) {
+ return new Link(rel, href);
+ }
+
+ public static Link create(String rel, String href, String description) {
+ return new Link(rel, href, description);
+ }
+
+ public static Link create(String rel, String href, boolean templated) {
+ return new Link(rel, href, templated);
+ }
+
+}
diff --git a/initializr-generator/src/main/groovy/io/spring/initializr/metadata/MetadataElement.groovy b/initializr-generator/src/main/java/io/spring/initializr/metadata/MetadataElement.java
similarity index 58%
rename from initializr-generator/src/main/groovy/io/spring/initializr/metadata/MetadataElement.groovy
rename to initializr-generator/src/main/java/io/spring/initializr/metadata/MetadataElement.java
index 4dabd3fd..234d8a3a 100644
--- a/initializr-generator/src/main/groovy/io/spring/initializr/metadata/MetadataElement.groovy
+++ b/initializr-generator/src/main/java/io/spring/initializr/metadata/MetadataElement.java
@@ -14,30 +14,51 @@
* limitations under the License.
*/
-package io.spring.initializr.metadata
-
-import groovy.transform.AutoClone
-import groovy.transform.AutoCloneStyle
+package io.spring.initializr.metadata;
/**
* A basic metadata element
*
* @author Stephane Nicoll
*/
-@AutoClone(style = AutoCloneStyle.COPY_CONSTRUCTOR)
-class MetadataElement {
+// @AutoClone(style = AutoCloneStyle.COPY_CONSTRUCTOR)
+public class MetadataElement {
/**
* A visual representation of this element.
*/
- String name
+ private String name;
/**
* The unique id of this element for a given capability.
*/
- String id
+ private String id;
+
+ public MetadataElement() {
+ }
- String getName() {
- (name ?: id)
+ public MetadataElement(MetadataElement other) {
+ this(other.id, other.name);
+ }
+
+ public MetadataElement(String id, String name) {
+ this.id = id;
+ this.name = name;
+ }
+
+ public String getName() {
+ return name!=null ? name: id;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public void setName(String name) {
+ this.name = name;
}
}
\ No newline at end of file
diff --git a/initializr-generator/src/main/java/io/spring/initializr/metadata/Repository.java b/initializr-generator/src/main/java/io/spring/initializr/metadata/Repository.java
new file mode 100644
index 00000000..506ee337
--- /dev/null
+++ b/initializr-generator/src/main/java/io/spring/initializr/metadata/Repository.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2012-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.
+ * You may obtain a copy of the License at
+ *
+ * http://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.metadata;
+
+import java.net.URL;
+
+/**
+ * Define a repository to be represented in the generated project if a dependency refers
+ * to it.
+ *
+ * @author Stephane Nicoll
+ */
+public class Repository {
+
+ private String name;
+ private URL url;
+ private boolean snapshotsEnabled;
+
+ public Repository() {
+ }
+
+ public Repository(String name, URL url, boolean snapshotsEnabled) {
+ this.name = name;
+ this.url = url;
+ this.snapshotsEnabled = snapshotsEnabled;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public URL getUrl() {
+ return url;
+ }
+
+ public void setUrl(URL url) {
+ this.url = url;
+ }
+
+ public boolean isSnapshotsEnabled() {
+ return snapshotsEnabled;
+ }
+
+ public void setSnapshotsEnabled(boolean snapshotsEnabled) {
+ this.snapshotsEnabled = snapshotsEnabled;
+ }
+
+ @Override
+ public String toString() {
+ return "Repository [" + (name != null ? "name=" + name + ", " : "")
+ + (url != null ? "url=" + url + ", " : "") + "snapshotsEnabled="
+ + snapshotsEnabled + "]";
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((name == null) ? 0 : name.hashCode());
+ result = prime * result + (snapshotsEnabled ? 1231 : 1237);
+ result = prime * result + ((url == null) ? 0 : url.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ Repository other = (Repository) obj;
+ if (name == null) {
+ if (other.name != null)
+ return false;
+ }
+ else if (!name.equals(other.name))
+ return false;
+ if (snapshotsEnabled != other.snapshotsEnabled)
+ return false;
+ if (url == null) {
+ if (other.url != null)
+ return false;
+ }
+ else if (!url.equals(other.url))
+ return false;
+ return true;
+ }
+
+}
diff --git a/initializr-generator/src/main/java/io/spring/initializr/metadata/ServiceCapability.java b/initializr-generator/src/main/java/io/spring/initializr/metadata/ServiceCapability.java
new file mode 100644
index 00000000..03341958
--- /dev/null
+++ b/initializr-generator/src/main/java/io/spring/initializr/metadata/ServiceCapability.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2012-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.
+ * You may obtain a copy of the License at
+ *
+ * http://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.metadata;
+
+import org.springframework.util.Assert;
+import org.springframework.util.StringUtils;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonInclude;
+
+/**
+ * Defines a capability of the initializr service. Each capability is defined by a id and
+ * a {@link ServiceCapabilityType type}.
+ *
+ * @author Stephane Nicoll
+ */
+@JsonIgnoreProperties({ "default", "all" })
+@JsonInclude(JsonInclude.Include.NON_NULL)
+// @AutoClone(style = AutoCloneStyle.COPY_CONSTRUCTOR)
+public abstract class ServiceCapability implements Cloneable {
+
+ private final String id;
+
+ private final ServiceCapabilityType type;
+
+ /**
+ * A title of the capability, used as a header text or label.
+ */
+ private String title;
+
+ /**
+ * A description of the capability, used in help usage or UI tooltips.
+ */
+ private String description;
+
+ public ServiceCapability(ServiceCapability other) {
+ this.id = other.id;
+ this.type = other.type;
+ merge(other);
+ }
+
+ protected ServiceCapability(String id, ServiceCapabilityType type) {
+ this.id = id;
+ this.type = type;
+ }
+
+ protected ServiceCapability(String id, ServiceCapabilityType type, String title,
+ String description) {
+ this.id = id;
+ this.type = type;
+ this.title = title;
+ this.description = description;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public ServiceCapabilityType getType() {
+ return type;
+ }
+
+ /**
+ * Return the "content" of this capability. The structure of the content vastly
+ * depends on the {@link ServiceCapability type} of the capability.
+ */
+ public abstract T getContent();
+
+ /**
+ * Merge the content of this instance with the specified content.
+ * @see #merge(io.spring.initializr.metadata.ServiceCapability)
+ */
+ public abstract void merge(T otherContent);
+
+ /**
+ * Merge this capability with the specified argument. The service capabilities should
+ * match (i.e have the same {@code id} and {@code type}). Sub-classes may merge
+ * additional content.
+ */
+ public void merge(ServiceCapability other) {
+ Assert.notNull(other, "Other must not be null");
+ Assert.state(this.id.equals(other.id));
+ Assert.state(this.type.equals(other.type));
+ if (StringUtils.hasText(other.title)) {
+ this.title = other.title;
+ }
+ if (StringUtils.hasText(other.description)) {
+ this.description = other.description;
+ }
+ merge(other.getContent());
+ }
+
+}
diff --git a/initializr-generator/src/main/groovy/io/spring/initializr/metadata/ServiceCapabilityType.groovy b/initializr-generator/src/main/java/io/spring/initializr/metadata/ServiceCapabilityType.java
similarity index 75%
rename from initializr-generator/src/main/groovy/io/spring/initializr/metadata/ServiceCapabilityType.groovy
rename to initializr-generator/src/main/java/io/spring/initializr/metadata/ServiceCapabilityType.java
index edd5a53b..d876409e 100644
--- a/initializr-generator/src/main/groovy/io/spring/initializr/metadata/ServiceCapabilityType.groovy
+++ b/initializr-generator/src/main/java/io/spring/initializr/metadata/ServiceCapabilityType.java
@@ -14,40 +14,44 @@
* limitations under the License.
*/
-package io.spring.initializr.metadata
+package io.spring.initializr.metadata;
/**
* Defines the supported service capability type.
*
* @author Stephane Nicoll
*/
-enum ServiceCapabilityType {
+public enum ServiceCapabilityType {
/**
* A special type that defines the action to use.
*/
- ACTION('action'),
+ ACTION("action"),
/**
* A simple text value with no option.
*/
- TEXT('text'),
+ TEXT("text"),
/**
* A simple value to be chosen amongst the specified options.
*/
- SINGLE_SELECT('single-select'),
+ SINGLE_SELECT("single-select"),
/**
* A hierarchical set of values (values in values) with the ability to
* select multiple values.
*/
- HIERARCHICAL_MULTI_SELECT('hierarchical-multi-select')
+ HIERARCHICAL_MULTI_SELECT("hierarchical-multi-select");
- final String name
+ final String name;
- ServiceCapabilityType(String name) {
- this.name = name
+ private ServiceCapabilityType(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
}
}
diff --git a/initializr-generator/src/main/groovy/io/spring/initializr/metadata/SimpleInitializrMetadataProvider.groovy b/initializr-generator/src/main/java/io/spring/initializr/metadata/SimpleInitializrMetadataProvider.java
similarity index 69%
rename from initializr-generator/src/main/groovy/io/spring/initializr/metadata/SimpleInitializrMetadataProvider.groovy
rename to initializr-generator/src/main/java/io/spring/initializr/metadata/SimpleInitializrMetadataProvider.java
index ff8ac995..69686953 100644
--- a/initializr-generator/src/main/groovy/io/spring/initializr/metadata/SimpleInitializrMetadataProvider.groovy
+++ b/initializr-generator/src/main/java/io/spring/initializr/metadata/SimpleInitializrMetadataProvider.java
@@ -14,23 +14,23 @@
* limitations under the License.
*/
-package io.spring.initializr.metadata
+package io.spring.initializr.metadata;
/**
* A simple {@link InitializrMetadataProvider} implementation.
*
* @author Stephane Nicoll
*/
-class SimpleInitializrMetadataProvider implements InitializrMetadataProvider {
+public class SimpleInitializrMetadataProvider implements InitializrMetadataProvider {
- private final InitializrMetadata metadata
+ private final InitializrMetadata metadata;
- SimpleInitializrMetadataProvider(InitializrMetadata metadata) {
- this.metadata = metadata
+ public SimpleInitializrMetadataProvider(InitializrMetadata metadata) {
+ this.metadata = metadata;
}
@Override
- InitializrMetadata get() {
- this.metadata
+ public InitializrMetadata get() {
+ return this.metadata;
}
}
diff --git a/initializr-generator/src/main/java/io/spring/initializr/metadata/SingleSelectCapability.java b/initializr-generator/src/main/java/io/spring/initializr/metadata/SingleSelectCapability.java
new file mode 100644
index 00000000..cdeb7c3a
--- /dev/null
+++ b/initializr-generator/src/main/java/io/spring/initializr/metadata/SingleSelectCapability.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2012-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.
+ * You may obtain a copy of the License at
+ *
+ * http://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.metadata;
+
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * A {@link ServiceCapabilityType#SINGLE_SELECT single select} capability.
+ *
+ * @author Stephane Nicoll
+ */
+public class SingleSelectCapability
+ extends ServiceCapability>
+ implements Defaultable {
+
+ private final List content = new CopyOnWriteArrayList();
+
+ @JsonCreator
+ SingleSelectCapability(@JsonProperty("id") String id) {
+ this(id, null, null);
+ }
+
+ public SingleSelectCapability(String id, String title, String description) {
+ super(id, ServiceCapabilityType.SINGLE_SELECT, title, description);
+ }
+
+ public List getContent() {
+ return content;
+ }
+
+ /**
+ * Return the default element of this capability.
+ */
+ public DefaultMetadataElement getDefault() {
+ return content.stream().filter(DefaultMetadataElement::isDefault).findFirst()
+ .orElse(null);
+ }
+
+ /**
+ * Return the element with the specified id or {@code null} if no such element exists.
+ */
+ public DefaultMetadataElement get(String id) {
+ return content.stream().filter(it -> id.equals(it.getId())).findFirst()
+ .orElse(null);
+ }
+
+ @Override
+ public void merge(List otherContent) {
+ otherContent.forEach(it -> {
+ if (get(it.getId()) == null) {
+ content.add(it);
+ }
+ });
+ }
+
+}
diff --git a/initializr-generator/src/main/groovy/io/spring/initializr/metadata/TextCapability.groovy b/initializr-generator/src/main/java/io/spring/initializr/metadata/TextCapability.java
similarity index 61%
rename from initializr-generator/src/main/groovy/io/spring/initializr/metadata/TextCapability.groovy
rename to initializr-generator/src/main/java/io/spring/initializr/metadata/TextCapability.java
index 81510caa..130c9c30 100644
--- a/initializr-generator/src/main/groovy/io/spring/initializr/metadata/TextCapability.groovy
+++ b/initializr-generator/src/main/java/io/spring/initializr/metadata/TextCapability.java
@@ -14,33 +14,41 @@
* limitations under the License.
*/
-package io.spring.initializr.metadata
+package io.spring.initializr.metadata;
-import com.fasterxml.jackson.annotation.JsonCreator
-import com.fasterxml.jackson.annotation.JsonProperty
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
/**
* A {@link ServiceCapabilityType#TEXT text} capability.
*
* @author Stephane Nicoll
*/
-class TextCapability extends ServiceCapability {
+public class TextCapability extends ServiceCapability {
- String content
+ private String content;
@JsonCreator
TextCapability(@JsonProperty("id") String id) {
- this(id, null, null)
+ this(id, null, null);
}
TextCapability(String id, String title, String description) {
- super(id, ServiceCapabilityType.TEXT, title, description)
+ super(id, ServiceCapabilityType.TEXT, title, description);
+ }
+
+ public String getContent() {
+ return content;
+ }
+
+ public void setContent(String content) {
+ this.content = content;
}
@Override
- void merge(String otherContent) {
- if (otherContent) {
- this.content = otherContent
+ public void merge(String otherContent) {
+ if (otherContent != null) {
+ this.content = otherContent;
}
}
diff --git a/initializr-generator/src/main/java/io/spring/initializr/metadata/Type.java b/initializr-generator/src/main/java/io/spring/initializr/metadata/Type.java
new file mode 100644
index 00000000..06d7f74d
--- /dev/null
+++ b/initializr-generator/src/main/java/io/spring/initializr/metadata/Type.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2012-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.
+ * You may obtain a copy of the License at
+ *
+ * http://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.metadata;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * Defines a particular project type. Each type is associated to a concrete action that
+ * should be invoked to generate the content of that type.
+ *
+ * @author Stephane Nicoll
+ */
+public class Type extends DefaultMetadataElement implements Describable {
+
+ private String description;
+
+ @Deprecated
+ private String stsId;
+
+ private String action;
+
+ private final Map tags = new LinkedHashMap<>();
+
+ public void setAction(String action) {
+ String actionToUse = action;
+ if (!actionToUse.startsWith("/")) {
+ actionToUse = "/" + actionToUse;
+ }
+ this.action = actionToUse;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public String getStsId() {
+ return stsId;
+ }
+
+ public void setStsId(String stsId) {
+ this.stsId = stsId;
+ }
+
+ public String getAction() {
+ return action;
+ }
+
+ public Map getTags() {
+ return tags;
+ }
+
+}
diff --git a/initializr-generator/src/main/groovy/io/spring/initializr/metadata/TypeCapability.groovy b/initializr-generator/src/main/java/io/spring/initializr/metadata/TypeCapability.java
similarity index 51%
rename from initializr-generator/src/main/groovy/io/spring/initializr/metadata/TypeCapability.groovy
rename to initializr-generator/src/main/java/io/spring/initializr/metadata/TypeCapability.java
index 19060a96..bf1e2d6c 100644
--- a/initializr-generator/src/main/groovy/io/spring/initializr/metadata/TypeCapability.groovy
+++ b/initializr-generator/src/main/java/io/spring/initializr/metadata/TypeCapability.java
@@ -14,47 +14,52 @@
* limitations under the License.
*/
-package io.spring.initializr.metadata
+package io.spring.initializr.metadata;
-import groovy.transform.AutoClone
-import groovy.transform.AutoCloneStyle
+import java.util.ArrayList;
+import java.util.List;
/**
* An {@link ServiceCapabilityType#ACTION action} capability.
*
* @author Stephane Nicoll
*/
-@AutoClone(style = AutoCloneStyle.COPY_CONSTRUCTOR)
-class TypeCapability extends ServiceCapability> {
+public class TypeCapability extends ServiceCapability> implements Defaultable {
- final List content = []
+ final List content = new ArrayList<>();
- TypeCapability() {
- super('type', ServiceCapabilityType.ACTION, 'Type', 'project type')
+ public TypeCapability() {
+ super("type", ServiceCapabilityType.ACTION, "Type", "project type");
+ }
+
+ public List getContent() {
+ return content;
}
/**
- * Return the {@link Type} with the specified id or {@code null} if no
- * such type exists.
+ * Return the {@link Type} with the specified id or {@code null} if no such type
+ * exists.
*/
- Type get(String id) {
- return content.find { id.equals(it.id) || id.equals(it.stsId) }
+ public Type get(String id) {
+ return content.stream()
+ .filter(it -> id.equals(it.getId()) || id.equals(it.getStsId()))
+ .findFirst().orElse(null);
}
/**
* Return the default {@link Type}.
*/
- Type getDefault() {
- return content.find { it.default }
+ public Type getDefault() {
+ return content.stream().filter(it -> it.isDefault()).findFirst().orElse(null);
}
@Override
- void merge(List otherContent) {
- otherContent.each {
- if (!get(it.id)) {
- content << it
+ public void merge(List otherContent) {
+ otherContent.forEach(it -> {
+ if (get(it.getId())==null) {
+ content.add(it);
}
- }
+ });
}
}
diff --git a/initializr-generator/src/main/java/io/spring/initializr/util/Agent.java b/initializr-generator/src/main/java/io/spring/initializr/util/Agent.java
new file mode 100644
index 00000000..55f17ffe
--- /dev/null
+++ b/initializr-generator/src/main/java/io/spring/initializr/util/Agent.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright 2012-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.
+ * You may obtain a copy of the License at
+ *
+ * http://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.util;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Defines the agent that submitted a request.
+ *
+ * @author Stephane Nicoll
+ */
+public class Agent {
+
+ /**
+ * The {@link AgentId}.
+ */
+ private final AgentId id;
+
+ /**
+ * The version of the agent, if any
+ */
+ private final String version;
+
+ public Agent(AgentId id, String version) {
+ this.id = id;
+ this.version = version;
+ }
+
+ public AgentId getId() {
+ return id;
+ }
+
+ public String getVersion() {
+ return version;
+ }
+
+ /**
+ * Create an {@link Agent} based on the specified {@code User-Agent} header.
+ * @param userAgent the user agent
+ * @return an {@link Agent} instance or {@code null}
+ */
+ public static Agent fromUserAgent(String userAgent) {
+ return UserAgentHandler.parse(userAgent);
+ }
+
+ /**
+ * Defines the various known agents.
+ */
+ public static enum AgentId {
+
+ CURL("curl", "curl"),
+
+ HTTPIE("httpie", "HTTPie"),
+
+ SPRING_BOOT_CLI("spring", "SpringBootCli"),
+
+ STS("sts", "STS"),
+
+ INTELLIJ_IDEA("intellijidea", "IntelliJ IDEA"),
+
+ NETBEANS("netbeans", "NetBeans"),
+
+ BROWSER("browser", "Browser");
+
+ final String id;
+ final String name;
+
+ public String getId() {
+ return id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ private AgentId(String id, String name) {
+ this.id = id;
+ this.name = name;
+ }
+ }
+
+ private static class UserAgentHandler {
+
+ private static final Pattern TOOL_REGEX = Pattern.compile("([^\\/]*)\\/([^ ]*).*");
+
+ private static final Pattern STS_REGEX = Pattern.compile("STS (.*)");
+
+ private static final Pattern NETBEANS_REGEX = Pattern.compile("nb-springboot-plugin\\/(.*)");
+
+ public static Agent parse(String userAgent) {
+ Matcher matcher = TOOL_REGEX.matcher(userAgent);
+ if (matcher.matches()) {
+ String name = matcher.group(1);
+ for (AgentId id : AgentId.values()) {
+ if (name.equals(id.name)) {
+ String version = matcher.group(2);
+ return new Agent(id, version);
+ }
+ }
+ }
+ matcher = STS_REGEX.matcher(userAgent);
+ if (matcher.matches()) {
+ return new Agent(AgentId.STS, matcher.group(1));
+ }
+ matcher = NETBEANS_REGEX.matcher(userAgent);
+ if (matcher.matches()) {
+ return new Agent(AgentId.NETBEANS, matcher.group(1));
+ }
+
+ if (userAgent.equals(AgentId.INTELLIJ_IDEA.name)) {
+ return new Agent(AgentId.INTELLIJ_IDEA, null);
+ }
+ if (userAgent.contains("Mozilla/5.0")) { // Super heuristics
+ return new Agent(AgentId.BROWSER, null);
+ }
+ return null;
+ }
+
+ }
+
+}
diff --git a/initializr-generator/src/main/java/io/spring/initializr/util/GroovyTemplate.java b/initializr-generator/src/main/java/io/spring/initializr/util/GroovyTemplate.java
new file mode 100644
index 00000000..d859ccfe
--- /dev/null
+++ b/initializr-generator/src/main/java/io/spring/initializr/util/GroovyTemplate.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2012-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.
+ * You may obtain a copy of the License at
+ *
+ * http://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.util;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.StringWriter;
+import java.net.URL;
+import java.nio.charset.Charset;
+import java.util.Map;
+import java.util.concurrent.ConcurrentMap;
+
+import org.codehaus.groovy.control.CompilationFailedException;
+import org.springframework.util.ConcurrentReferenceHashMap;
+import org.springframework.util.StreamUtils;
+
+import groovy.lang.Writable;
+import groovy.text.GStringTemplateEngine;
+import groovy.text.Template;
+import groovy.text.TemplateEngine;
+
+/**
+ * @author Dave Syer
+ */
+public class GroovyTemplate {
+
+ private boolean cache = true;
+
+ private final TemplateEngine engine;
+ private final ConcurrentMap templateCaches = new ConcurrentReferenceHashMap<>();
+
+ public GroovyTemplate(TemplateEngine engine) {
+ this.engine = engine;
+ }
+
+ public GroovyTemplate() {
+ this(new GStringTemplateEngine());
+ }
+
+ public boolean isCache() {
+ return cache;
+ }
+
+ public void setCache(boolean cache) {
+ this.cache = cache;
+ }
+
+ public String process(String name, Map model) {
+ try {
+ Template template = getTemplate(name);
+ Writable writable = template.make(model);
+ StringWriter result = new StringWriter();
+ writable.writeTo(result);
+ return result.toString();
+ }
+ catch (Exception e) {
+ throw new IllegalStateException("Cannot render template", e);
+ }
+ }
+
+ public Template getTemplate(String name)
+ throws CompilationFailedException, ClassNotFoundException, IOException {
+ if (cache) {
+ return this.templateCaches.computeIfAbsent(name, n -> loadTemplate(n));
+ }
+ return loadTemplate(name);
+ }
+
+ protected Template loadTemplate(String name) {
+ try {
+ File file = new File("templates", name);
+ if (file.exists()) {
+ return engine.createTemplate(file);
+ }
+
+ ClassLoader classLoader = GroovyTemplate.class.getClassLoader();
+ URL resource = classLoader.getResource("templates/" + name);
+ if (resource != null) {
+ return engine.createTemplate(StreamUtils
+ .copyToString(resource.openStream(), Charset.forName("UTF-8")));
+ }
+
+ return engine.createTemplate(name);
+ }
+ catch (Exception e) {
+ throw new IllegalStateException("Cannot load template " + name, e);
+ }
+ }
+
+}
diff --git a/initializr-generator/src/main/groovy/io/spring/initializr/util/InvalidVersionException.groovy b/initializr-generator/src/main/java/io/spring/initializr/util/InvalidVersionException.java
similarity index 70%
rename from initializr-generator/src/main/groovy/io/spring/initializr/util/InvalidVersionException.groovy
rename to initializr-generator/src/main/java/io/spring/initializr/util/InvalidVersionException.java
index 1d5b174e..1a93d61e 100644
--- a/initializr-generator/src/main/groovy/io/spring/initializr/util/InvalidVersionException.groovy
+++ b/initializr-generator/src/main/java/io/spring/initializr/util/InvalidVersionException.java
@@ -14,16 +14,22 @@
* limitations under the License.
*/
-package io.spring.initializr.util
-
-import groovy.transform.InheritConstructors
+package io.spring.initializr.util;
/**
* Thrown if a input represents an invalid version.
*
* @author Stephane Nicoll
*/
-@InheritConstructors
-class InvalidVersionException extends RuntimeException {
+@SuppressWarnings("serial")
+public class InvalidVersionException extends RuntimeException {
+
+ public InvalidVersionException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public InvalidVersionException(String message) {
+ super(message);
+ }
}
diff --git a/initializr-generator/src/main/java/io/spring/initializr/util/Version.java b/initializr-generator/src/main/java/io/spring/initializr/util/Version.java
new file mode 100644
index 00000000..3dfb8f58
--- /dev/null
+++ b/initializr-generator/src/main/java/io/spring/initializr/util/Version.java
@@ -0,0 +1,290 @@
+/*
+ * Copyright 2012-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.
+ * You may obtain a copy of the License at
+ *
+ * http://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.util;
+
+import java.io.Serializable;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+import org.springframework.util.StringUtils;
+
+/**
+ * Define the version number of a module. A typical version is represented
+ * as {@code MAJOR.MINOR.PATCH.QUALIFIER} where the qualifier can have an
+ * extra version.
+ *
+ * For example: {@code 1.2.0.RC1} is the first release candidate of 1.2.0
+ * and {@code 1.5.0.M4} is the fourth milestone of 1.5.0. The special
+ * {@code RELEASE} qualifier indicates a final release (a.k.a. GA)
+ *
+ * The main purpose of parsing a version is to compare it with another
+ * version, see {@link Comparable}.
+ *
+ * @author Stephane Nicoll
+ */
+@SuppressWarnings("serial")
+public final class Version implements Serializable, Comparable {
+
+ private static final VersionQualifierComparator qualifierComparator = new VersionQualifierComparator();
+
+ private static final VersionParser parser = new VersionParser(Collections.emptyList());
+
+ private final Integer major;
+ private final Integer minor;
+ private final Integer patch;
+ private final Qualifier qualifier;
+
+ // For Jackson
+ @SuppressWarnings("unused")
+ private Version() {
+ this(null, null, null, null);
+ }
+
+ public Version(Integer major, Integer minor, Integer patch, Qualifier qualifier) {
+ this.major = major;
+ this.minor = minor;
+ this.patch = patch;
+ this.qualifier = qualifier;
+ }
+
+ public Integer getMajor() {
+ return major;
+ }
+
+ public Integer getMinor() {
+ return minor;
+ }
+
+ public Integer getPatch() {
+ return patch;
+ }
+
+ public Qualifier getQualifier() {
+ return qualifier;
+ }
+
+ @Override
+ public String toString() {
+ return major + "." + minor + "." + patch +
+ (qualifier!=null ? "." + qualifier.qualifier +
+ (qualifier.version!=null ? qualifier.version : "") : "");
+ }
+
+ /**
+ * Parse the string representation of a {@link Version}. Throws an
+ * {@link InvalidVersionException} if the version could not be parsed.
+ * @param text the version text
+ * @return a Version instance for the specified version text
+ * @throws InvalidVersionException if the version text could not be parsed
+ * @see {@link VersionParser}
+ */
+ public static Version parse(String text) {
+ return parser.parse(text);
+ }
+
+ /**
+ * Parse safely the specified string representation of a {@link Version}.
+ *
+ * Return {@code null} if the text represents an invalid version.
+ * @param text the version text
+ * @return a Version instance for the specified version text
+ * @see {@link VersionParser}
+ */
+ public static Version safeParse(String text) {
+ try {
+ return parse(text);
+ } catch (InvalidVersionException e) {
+ return null;
+ }
+ }
+
+ @Override
+ public int compareTo(Version other) {
+ if (other == null) {
+ return 1;
+ }
+ int majorDiff = safeCompare(this.major, other.major);
+ if (majorDiff != 0) {
+ return majorDiff;
+ }
+ int minorDiff = safeCompare(this.minor, other.minor);
+ if (minorDiff != 0) {
+ return minorDiff;
+ }
+ int patch = safeCompare(this.patch, other.patch);
+ if (patch != 0) {
+ return patch;
+ }
+ return qualifierComparator.compare(this.qualifier, other.qualifier);
+ }
+
+ private static int safeCompare(Integer first, Integer second) {
+ Integer firstIndex = first !=null ? first : 0;
+ Integer secondIndex = second !=null ? second : 0;
+ return firstIndex.compareTo(secondIndex);
+ }
+
+ public static class Qualifier {
+ public Qualifier() {
+ }
+ public Qualifier(String qualifier) {
+ this.qualifier = qualifier;
+ }
+ String qualifier;
+ Integer version;
+ public String getQualifier() {
+ return qualifier;
+ }
+ public void setQualifier(String qualifier) {
+ this.qualifier = qualifier;
+ }
+ public Integer getVersion() {
+ return version;
+ }
+ public void setVersion(Integer version) {
+ this.version = version;
+ }
+ @Override
+ public String toString() {
+ return "Qualifier ["
+ + (qualifier != null ? "qualifier=" + qualifier + ", " : "")
+ + (version != null ? "version=" + version : "") + "]";
+ }
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((qualifier == null) ? 0 : qualifier.hashCode());
+ result = prime * result + ((version == null) ? 0 : version.hashCode());
+ return result;
+ }
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ Qualifier other = (Qualifier) obj;
+ if (qualifier == null) {
+ if (other.qualifier != null)
+ return false;
+ }
+ else if (!qualifier.equals(other.qualifier))
+ return false;
+ if (version == null) {
+ if (other.version != null)
+ return false;
+ }
+ else if (!version.equals(other.version))
+ return false;
+ return true;
+ }
+ }
+
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((major == null) ? 0 : major.hashCode());
+ result = prime * result + ((minor == null) ? 0 : minor.hashCode());
+ result = prime * result + ((patch == null) ? 0 : patch.hashCode());
+ result = prime * result + ((qualifier == null) ? 0 : qualifier.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ Version other = (Version) obj;
+ if (major == null) {
+ if (other.major != null)
+ return false;
+ }
+ else if (!major.equals(other.major))
+ return false;
+ if (minor == null) {
+ if (other.minor != null)
+ return false;
+ }
+ else if (!minor.equals(other.minor))
+ return false;
+ if (patch == null) {
+ if (other.patch != null)
+ return false;
+ }
+ else if (!patch.equals(other.patch))
+ return false;
+ if (qualifier == null) {
+ if (other.qualifier != null)
+ return false;
+ }
+ else if (!qualifier.equals(other.qualifier))
+ return false;
+ return true;
+ }
+
+ private static class VersionQualifierComparator implements Comparator {
+
+ static final String RELEASE = "RELEASE";
+ static final String SNAPSHOT = "BUILD-SNAPSHOT";
+ static final String MILESTONE = "M";
+ static final String RC = "RC";
+
+ static final List KNOWN_QUALIFIERS = Arrays.asList(MILESTONE, RC, SNAPSHOT, RELEASE);
+
+ @Override
+ public int compare(Qualifier o1, Qualifier o2) {
+ Qualifier first = o1!=null ? o1 : new Qualifier(RELEASE);
+ Qualifier second = o2!=null ? o2 : new Qualifier(RELEASE);
+
+ int qualifier = compareQualifier(first, second);
+ return qualifier!=0 ? qualifier : compareQualifierVersion(first, second);
+ }
+
+ private static int compareQualifierVersion(Qualifier first, Qualifier second) {
+ Integer firstVersion = first.getVersion()!=null ? first.getVersion() : 0;
+ Integer secondVersion = second.getVersion()!=null ? second.getVersion(): 0;
+ return firstVersion.compareTo(secondVersion);
+ }
+
+ private static int compareQualifier(Qualifier first, Qualifier second) {
+ Integer firstIndex = getQualifierIndex(first.qualifier);
+ Integer secondIndex = getQualifierIndex(second.qualifier);
+
+ if (firstIndex == -1 && secondIndex == -1) { // Unknown qualifier, alphabetic ordering
+ return first.qualifier.compareTo(second.qualifier);
+ } else {
+ return firstIndex.compareTo(secondIndex);
+ }
+ }
+
+ private static int getQualifierIndex(String qualifier) {
+ return StringUtils.hasText(qualifier) ? KNOWN_QUALIFIERS.indexOf(qualifier) : 0;
+ }
+ }
+
+}
diff --git a/initializr-generator/src/main/groovy/io/spring/initializr/util/VersionParser.groovy b/initializr-generator/src/main/java/io/spring/initializr/util/VersionParser.java
similarity index 52%
rename from initializr-generator/src/main/groovy/io/spring/initializr/util/VersionParser.groovy
rename to initializr-generator/src/main/java/io/spring/initializr/util/VersionParser.java
index a9cae65a..a224de3c 100644
--- a/initializr-generator/src/main/groovy/io/spring/initializr/util/VersionParser.groovy
+++ b/initializr-generator/src/main/java/io/spring/initializr/util/VersionParser.java
@@ -14,9 +14,18 @@
* limitations under the License.
*/
-package io.spring.initializr.util
+package io.spring.initializr.util;
-import org.springframework.util.Assert
+import java.util.Collections;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+import org.springframework.util.Assert;
+import org.springframework.util.StringUtils;
+
+import io.spring.initializr.util.Version.Qualifier;
/**
* Parser for {@link Version} and {@link VersionRange} that allows to resolve the minor
@@ -31,18 +40,18 @@ import org.springframework.util.Assert
*
* @author Stephane Nicoll
*/
-class VersionParser {
+public class VersionParser {
- public static final VersionParser DEFAULT = new VersionParser(Collections.emptyList())
+ public static final VersionParser DEFAULT = new VersionParser(Collections.emptyList());
- private static final String VERSION_REGEX = '^(\\d+)\\.(\\d+|x)\\.(\\d+|x)(?:\\.([^0-9]+)(\\d+)?)?$'
+ private static final Pattern VERSION_REGEX = Pattern.compile("^(\\d+)\\.(\\d+|x)\\.(\\d+|x)(?:\\.([^0-9]+)(\\d+)?)?$");
- private static final String RANGE_REGEX = "(\\(|\\[)(.*),(.*)(\\)|\\])"
+ private static final Pattern RANGE_REGEX = Pattern.compile("(\\(|\\[)(.*),(.*)(\\)|\\])");
private final List latestVersions;
- VersionParser(List latestVersions) {
- this.latestVersions = latestVersions
+ public VersionParser(List latestVersions) {
+ this.latestVersions = latestVersions;
}
/**
@@ -53,35 +62,35 @@ class VersionParser {
* @throws InvalidVersionException if the version text could not be parsed
* @see #safeParse(java.lang.String)
*/
- Version parse(String text) {
- Assert.notNull(text, 'Text must not be null')
- def matcher = (text.trim() =~ VERSION_REGEX)
+ public Version parse(String text) {
+ Assert.notNull(text, "Text must not be null");
+ Matcher matcher = VERSION_REGEX.matcher(text.trim());
if (!matcher.matches()) {
- throw new InvalidVersionException("Could not determine version based on '$text': version format " +
- "is Minor.Major.Patch.Qualifier (e.g. 1.0.5.RELEASE)")
+ throw new InvalidVersionException("Could not determine version based on '" + text + "': version format " +
+ "is Minor.Major.Patch.Qualifier (e.g. 1.0.5.RELEASE)");
}
- Integer major = Integer.valueOf(matcher[0][1])
- String minor = matcher[0][2]
- String patch = matcher[0][3]
- def qualifier = null;
- String qualifierId = matcher[0][4]
- if (qualifierId) {
- qualifier = new Version.Qualifier(qualifier: qualifierId)
- String o = matcher[0][5]
+ Integer major = Integer.valueOf(matcher.group(1));
+ String minor = matcher.group(2);
+ String patch = matcher.group(3);
+ Qualifier qualifier = null;
+ String qualifierId = matcher.group(4);
+ if (StringUtils.hasText(qualifierId)) {
+ qualifier = new Version.Qualifier(qualifierId);
+ String o = matcher.group(5);
if (o != null) {
- qualifier.version = Integer.valueOf(o)
+ qualifier.version = Integer.valueOf(o);
}
}
- if (minor == "x" || patch == "x") {
- Integer minorInt = minor == "x" ? null : Integer.parseInt(minor)
- Version latest = findLatestVersion(major, minorInt, qualifier)
- if (!latest) {
- return new Version(major, (minor == "x" ? 999 : Integer.parseInt(minor)),
- (patch == "x" ? 999 : Integer.parseInt(patch)), qualifier)
+ if ("x".equals(minor) || "x".equals(patch)) {
+ Integer minorInt = "x".equals(minor) ? null : Integer.parseInt(minor);
+ Version latest = findLatestVersion(major, minorInt, qualifier);
+ if (latest==null) {
+ return new Version(major, ("x".equals(minor) ? 999 : Integer.parseInt(minor)),
+ ("x".equals(patch) ? 999 : Integer.parseInt(patch)), qualifier);
}
- return new Version(major, latest.minor, latest.patch, latest.qualifier)
+ return new Version(major, latest.getMinor(), latest.getPatch(), latest.getQualifier());
} else {
- return new Version(major, Integer.parseInt(minor), Integer.parseInt(patch), qualifier)
+ return new Version(major, Integer.parseInt(minor), Integer.parseInt(patch), qualifier);
}
}
@@ -93,11 +102,11 @@ class VersionParser {
* @return a Version instance for the specified version text
* @see #parse(java.lang.String)
*/
- Version safeParse(String text) {
+ public Version safeParse(String text) {
try {
- return parse(text)
+ return parse(text);
} catch (InvalidVersionException ex) {
- return null
+ return null;
}
}
@@ -108,36 +117,36 @@ class VersionParser {
* @return a VersionRange instance for the specified range text
* @throws InvalidVersionException if the range text could not be parsed
*/
- VersionRange parseRange(String text) {
- Assert.notNull(text, "Text must not be null")
- def matcher = (text.trim() =~ RANGE_REGEX)
+ public VersionRange parseRange(String text) {
+ Assert.notNull(text, "Text must not be null");
+ Matcher matcher = RANGE_REGEX.matcher(text.trim());
if (!matcher.matches()) {
// Try to read it as simple string
- Version version = parse(text)
- return new VersionRange(version, true, null, true)
+ Version version = parse(text);
+ return new VersionRange(version, true, null, true);
}
- boolean lowerInclusive = matcher[0][1].equals('[')
- Version lowerVersion = parse(matcher[0][2])
- Version higherVersion = parse(matcher[0][3])
- boolean higherInclusive = matcher[0][4].equals(']')
- new VersionRange(lowerVersion, lowerInclusive, higherVersion, higherInclusive)
+ boolean lowerInclusive = matcher.group(1).equals("[");
+ Version lowerVersion = parse(matcher.group(2));
+ Version higherVersion = parse(matcher.group(3));
+ boolean higherInclusive = matcher.group(4).equals("]");
+ return new VersionRange(lowerVersion, lowerInclusive, higherVersion, higherInclusive);
}
private Version findLatestVersion(Integer major, Integer minor,
Version.Qualifier qualifier) {
- def matches = this.latestVersions.findAll {
- if (major && major != it.major) {
+ List matches = this.latestVersions.stream().filter(it -> {
+ if (major!=null && !major.equals(it.getMajor())) {
return false;
}
- if (minor && minor != it.minor) {
+ if (minor!=null && !minor.equals(it.getMinor())) {
return false;
}
- if (qualifier && it.qualifier != qualifier) {
+ if (qualifier!=null && !qualifier.equals(it.getQualifier())) {
return false;
}
return true;
- }
- return (matches.size() == 1 ? matches[0] : null)
+ }).collect(Collectors.toList());
+ return (matches.size() == 1 ? matches.get(0) : null);
}
}
diff --git a/initializr-generator/src/main/java/io/spring/initializr/util/VersionRange.java b/initializr-generator/src/main/java/io/spring/initializr/util/VersionRange.java
new file mode 100644
index 00000000..bd3cf36c
--- /dev/null
+++ b/initializr-generator/src/main/java/io/spring/initializr/util/VersionRange.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright 2012-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.
+ * You may obtain a copy of the License at
+ *
+ * http://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.util;
+
+import org.springframework.util.Assert;
+
+/**
+ * Define a {@link Version} range. A square bracket "[" or "]" denotes an inclusive
+ * end of the range and a round bracket "(" or ")" denotes an exclusive end of the
+ * range. A range can also be unbounded by defining a a single {@link Version}. The
+ * examples below make this clear.
+ *
+ *
+ *
"[1.2.0.RELEASE,1.3.0.RELEASE)" version 1.2.0 and any version after
+ * this, up to, but not including, version 1.3.0.
+ *
"(2.0.0.RELEASE,3.2.0.RELEASE]" any version after 2.0.0 up to and
+ * including version 3.2.0.
+ *
"1.4.5.RELEASE", version 1.4.5 and all later versions.
+ *
+ *
+ * @author Stephane Nicoll
+ */
+public class VersionRange {
+
+ final Version lowerVersion;
+ final boolean lowerInclusive;
+ final Version higherVersion;
+ final boolean higherInclusive;
+
+ // For Jackson
+ @SuppressWarnings("unused")
+ private VersionRange() {
+ this(null, false, null, false);
+ }
+
+ protected VersionRange(Version lowerVersion, boolean lowerInclusive,
+ Version higherVersion, boolean higherInclusive) {
+ this.lowerVersion = lowerVersion;
+ this.lowerInclusive = lowerInclusive;
+ this.higherVersion = higherVersion;
+ this.higherInclusive = higherInclusive;
+ }
+
+ /**
+ * Specify if the {@link Version} matches this range. Returns {@code true}
+ * if the version is contained within this range, {@code false} otherwise.
+ */
+ public boolean match(Version version) {
+ Assert.notNull(version, "Version must not be null");
+ int lower = lowerVersion.compareTo(version);
+ if (lower > 0) {
+ return false;
+ } else if (!lowerInclusive && lower == 0) {
+ return false;
+ }
+ if (higherVersion!=null) {
+ int higher = higherVersion.compareTo(version);
+ if (higher < 0) {
+ return false;
+ } else if (!higherInclusive && higher == 0) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public Version getLowerVersion() {
+ return lowerVersion;
+ }
+
+ public boolean isLowerInclusive() {
+ return lowerInclusive;
+ }
+
+ public Version getHigherVersion() {
+ return higherVersion;
+ }
+
+ public boolean isHigherInclusive() {
+ return higherInclusive;
+ }
+
+ @Override
+ public
+ String toString() {
+ StringBuffer sb = new StringBuffer();
+ if (lowerVersion!=null) {
+ sb.append((lowerInclusive ? ">=" : ">") + lowerVersion);
+ }
+ if (higherVersion!=null) {
+ sb.append(" and " + (higherInclusive ? "<=" : "<") + higherVersion);
+ }
+ return sb.toString();
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + (higherInclusive ? 1231 : 1237);
+ result = prime * result
+ + ((higherVersion == null) ? 0 : higherVersion.hashCode());
+ result = prime * result + (lowerInclusive ? 1231 : 1237);
+ result = prime * result + ((lowerVersion == null) ? 0 : lowerVersion.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ VersionRange other = (VersionRange) obj;
+ if (higherInclusive != other.higherInclusive)
+ return false;
+ if (higherVersion == null) {
+ if (other.higherVersion != null)
+ return false;
+ }
+ else if (!higherVersion.equals(other.higherVersion))
+ return false;
+ if (lowerInclusive != other.lowerInclusive)
+ return false;
+ if (lowerVersion == null) {
+ if (other.lowerVersion != null)
+ return false;
+ }
+ else if (!lowerVersion.equals(other.lowerVersion))
+ return false;
+ return true;
+ }
+
+}
diff --git a/initializr-generator/src/main/resources/templates/starter-build.gradle b/initializr-generator/src/main/resources/templates/starter-build.gradle
index 5a684213..d10c34d0 100644
--- a/initializr-generator/src/main/resources/templates/starter-build.gradle
+++ b/initializr-generator/src/main/resources/templates/starter-build.gradle
@@ -1,6 +1,6 @@
buildscript {
ext {<% buildProperties.gradle.each { %>
- ${it.key} = '${it.value.call()}'<% } %>
+ ${it.key} = '${((java.util.function.Supplier)it.value).get()}'<% } %>
}
repositories {
mavenCentral()<% if (!bootVersion.contains("RELEASE")) { %>
@@ -39,7 +39,7 @@ repositories {
providedRuntime
}
<% } %><% if (buildProperties.versions) { %><%buildProperties.versions.each { %>
-ext['${it.key}'] = '${it.value.call()}'<% } %>
+ext['${it.key}'] = '${((java.util.function.Supplier)it.value).get()}'<% } %>
<% } %>
dependencies {<% compileDependencies.each { %>
compile('${it.groupId}:${it.artifactId}${it.version ? ":$it.version" : ""}${it.type ? "@$it.type" : ""}')<% } %><% if (language=='groovy') { %>
diff --git a/initializr-generator/src/main/resources/templates/starter-pom.xml b/initializr-generator/src/main/resources/templates/starter-pom.xml
index 452a25aa..83a8d0db 100644
--- a/initializr-generator/src/main/resources/templates/starter-pom.xml
+++ b/initializr-generator/src/main/resources/templates/starter-pom.xml
@@ -19,8 +19,8 @@
<% buildProperties.maven.each { %>
- <${it.key}>${it.value()}${it.key}><% } %><%buildProperties.versions.each { %>
- <${it.key}>${it.value()}${it.key}><%}%>
+ <${it.key}>${((java.util.function.Supplier)it.value).get()}${it.key}><% } %><%buildProperties.versions.each { %>
+ <${it.key}>${((java.util.function.Supplier)it.value).get()}${it.key}><%}%>
<% compileDependencies.each { %>
diff --git a/initializr-generator/src/test/groovy/io/spring/initializr/generator/AbstractProjectGeneratorTests.groovy b/initializr-generator/src/test/groovy/io/spring/initializr/generator/AbstractProjectGeneratorTests.groovy
deleted file mode 100644
index 6fb22d38..00000000
--- a/initializr-generator/src/test/groovy/io/spring/initializr/generator/AbstractProjectGeneratorTests.groovy
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright 2012-2016 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
- *
- * http://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
-
-import io.spring.initializr.metadata.Dependency
-import io.spring.initializr.metadata.InitializrMetadata
-import io.spring.initializr.metadata.SimpleInitializrMetadataProvider
-import io.spring.initializr.test.generator.GradleBuildAssert
-import io.spring.initializr.test.generator.PomAssert
-import io.spring.initializr.test.generator.ProjectAssert
-import io.spring.initializr.test.metadata.InitializrMetadataTestBuilder
-import org.junit.Before
-import org.junit.Rule
-import org.junit.rules.TemporaryFolder
-import org.mockito.ArgumentMatcher
-
-import org.springframework.context.ApplicationEventPublisher
-
-import static org.mockito.Matchers.argThat
-import static org.mockito.Mockito.mock
-import static org.mockito.Mockito.times
-import static org.mockito.Mockito.verify
-
-/**
- *
- * @author Stephane Nicoll
- */
-abstract class AbstractProjectGeneratorTests {
-
- @Rule
- public final TemporaryFolder folder = new TemporaryFolder()
-
- protected final ProjectGenerator projectGenerator = new ProjectGenerator()
-
- private final ApplicationEventPublisher eventPublisher = mock(ApplicationEventPublisher)
-
- @Before
- void setup() {
- def web = new Dependency(id: 'web')
- web.facets << 'web'
- def metadata = InitializrMetadataTestBuilder.withDefaults()
- .addDependencyGroup('web', web)
- .addDependencyGroup('test', 'security', 'data-jpa', 'aop', 'batch', 'integration').build()
- applyMetadata(metadata)
- projectGenerator.eventPublisher = eventPublisher
- projectGenerator.requestResolver = new ProjectRequestResolver([])
- projectGenerator.tmpdir = folder.newFolder().absolutePath
- }
-
-
- protected PomAssert generateMavenPom(ProjectRequest request) {
- request.type = 'maven-build'
- def content = new String(projectGenerator.generateMavenPom(request))
- new PomAssert(content).validateProjectRequest(request)
- }
-
- protected GradleBuildAssert generateGradleBuild(ProjectRequest request) {
- request.type = 'gradle-build'
- def content = new String(projectGenerator.generateGradleBuild(request))
- new GradleBuildAssert(content).validateProjectRequest(request)
- }
-
- protected ProjectAssert generateProject(ProjectRequest request) {
- def dir = projectGenerator.generateProjectStructure(request)
- new ProjectAssert(dir)
- }
-
- ProjectRequest createProjectRequest(String... styles) {
- def request = new ProjectRequest()
- request.initialize(projectGenerator.metadataProvider.get())
- request.style.addAll Arrays.asList(styles)
- request
- }
-
- protected void applyMetadata(InitializrMetadata metadata) {
- projectGenerator.metadataProvider = new SimpleInitializrMetadataProvider(metadata)
- }
-
- protected verifyProjectSuccessfulEventFor(ProjectRequest request) {
- verify(eventPublisher, times(1)).publishEvent(argThat(new ProjectGeneratedEventMatcher(request)))
- }
-
- protected verifyProjectFailedEventFor(ProjectRequest request, Exception ex) {
- verify(eventPublisher, times(1)).publishEvent(argThat(new ProjectFailedEventMatcher(request, ex)))
- }
-
- private static class ProjectGeneratedEventMatcher extends ArgumentMatcher {
-
- private final ProjectRequest request
-
- ProjectGeneratedEventMatcher(ProjectRequest request) {
- this.request = request
- }
-
- @Override
- boolean matches(Object argument) {
- ProjectGeneratedEvent event = (ProjectGeneratedEvent) argument
- return request.equals(event.projectRequest)
- }
- }
-
- private static class ProjectFailedEventMatcher extends ArgumentMatcher {
-
- private final ProjectRequest request
- private final Exception cause
-
- ProjectFailedEventMatcher(ProjectRequest request, Exception cause) {
- this.request = request
- this.cause = cause
- }
-
- @Override
- boolean matches(Object argument) {
- ProjectFailedEvent event = (ProjectFailedEvent) argument
- return request.equals(event.projectRequest) && cause.equals(event.cause)
- }
- }
-
-
-}
diff --git a/initializr-generator/src/test/groovy/io/spring/initializr/generator/CommandLineHelpGeneratorTests.groovy b/initializr-generator/src/test/groovy/io/spring/initializr/generator/CommandLineHelpGeneratorTests.groovy
deleted file mode 100644
index d32bf43b..00000000
--- a/initializr-generator/src/test/groovy/io/spring/initializr/generator/CommandLineHelpGeneratorTests.groovy
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright 2012-2016 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
- *
- * http://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
-
-import io.spring.initializr.metadata.Dependency
-import io.spring.initializr.metadata.Type
-import io.spring.initializr.test.metadata.InitializrMetadataTestBuilder
-import io.spring.initializr.util.GroovyTemplate
-import org.junit.Test
-
-import static org.hamcrest.CoreMatchers.containsString
-import static org.hamcrest.core.IsNot.not
-import static org.junit.Assert.assertThat
-
-/**
- * @author Stephane Nicoll
- */
-class CommandLineHelpGeneratorTests {
-
- private CommandLineHelpGenerator generator = new CommandLineHelpGenerator(new GroovyTemplate())
-
- @Test
- void generateGenericCapabilities() {
- def metadata = InitializrMetadataTestBuilder.withDefaults().addDependencyGroup("test",
- createDependency('id-b', 'depB'),
- createDependency('id-a', 'depA', 'and some description')).build()
- String content = generator.generateGenericCapabilities(metadata, "https://fake-service")
- assertCommandLineCapabilities(content)
- assertThat content, containsString('id-a | and some description |')
- assertThat content, containsString('id-b | depB')
- assertThat content, containsString("https://fake-service")
- assertThat content, not(containsString('Examples:'))
- assertThat content, not(containsString('curl'))
- }
-
- @Test
- void generateCapabilitiesWithTypeDescription() {
- def metadata = InitializrMetadataTestBuilder.withDefaults()
- .addType(new Type(id: 'foo', name: 'foo-name', description: 'foo-desc'))
- .build()
- String content = generator.generateGenericCapabilities(metadata, "https://fake-service")
- assertCommandLineCapabilities(content)
- assertThat content, containsString('| foo')
- assertThat content, containsString('| foo-desc')
- }
-
- @Test
- void generateCurlCapabilities() {
- def metadata = InitializrMetadataTestBuilder.withDefaults().addDependencyGroup("test",
- createDependency('id-b', 'depB'),
- createDependency('id-a', 'depA', 'and some description')).build()
- String content = generator.generateCurlCapabilities(metadata, "https://fake-service")
- assertCommandLineCapabilities(content)
- assertThat content, containsString('id-a | and some description |')
- assertThat content, containsString('id-b | depB')
- assertThat content, containsString("https://fake-service")
- assertThat content, containsString('Examples:')
- assertThat content, containsString('curl')
- }
-
- @Test
- void generateHttpCapabilities() {
- def metadata = InitializrMetadataTestBuilder.withDefaults().addDependencyGroup("test",
- createDependency('id-b', 'depB'),
- createDependency('id-a', 'depA', 'and some description')).build()
- String content = generator.generateHttpieCapabilities(metadata, "https://fake-service")
- assertCommandLineCapabilities(content)
- assertThat content, containsString('id-a | and some description |')
- assertThat content, containsString('id-b | depB')
- assertThat content, containsString("https://fake-service")
- assertThat content, containsString('Examples:')
- assertThat content, not(containsString('curl'))
- assertThat content, containsString("http https://fake-service")
- }
-
- @Test
- void generateSpringBootCliCapabilities() {
- def metadata = InitializrMetadataTestBuilder.withDefaults().addDependencyGroup("test",
- createDependency('id-b', 'depB'),
- createDependency('id-a', 'depA', 'and some description')).build()
- String content = generator.generateSpringBootCliCapabilities(metadata, "https://fake-service")
- assertThat content, containsString("| Id")
- assertThat content, containsString("| Tags")
- assertThat content, containsString('id-a | and some description |')
- assertThat content, containsString('id-b | depB')
- assertThat content, containsString("https://fake-service")
- assertThat content, not(containsString('Examples:'))
- assertThat content, not(containsString('curl'))
- assertThat content, not(containsString('| Rel'))
- assertThat content, not(containsString("| dependencies"))
- assertThat content, not(containsString("| applicationName"))
- assertThat content, not(containsString("| baseDir"))
- }
-
- @Test
- void generateCapabilitiesWithVersionRange() {
- def first = new Dependency(id: 'first', description: 'first desc', versionRange: '1.2.0.RELEASE')
- def second = new Dependency(id: 'second', description: 'second desc', versionRange: ' [1.2.0.RELEASE,1.3.0.M1) ')
- def metadata = InitializrMetadataTestBuilder.withDefaults().addDependencyGroup("test", first, second).build()
- String content = generator.generateSpringBootCliCapabilities(metadata, "https://fake-service")
- assertThat content, containsString('| first | first desc | >=1.2.0.RELEASE |')
- assertThat content, containsString('| second | second desc | >=1.2.0.RELEASE and <1.3.0.M1 |')
- }
-
- private static assertCommandLineCapabilities(String content) {
- assertThat content, containsString("| Rel")
- assertThat content, containsString("| dependencies")
- assertThat content, containsString("| applicationName")
- assertThat content, containsString("| baseDir")
- assertThat content, not(containsString('| Tags'))
- }
-
- private static createDependency(String id, String name) {
- createDependency(id, name, null)
- }
-
- private static createDependency(String id, String name, String description) {
- new Dependency(id: id, name: name, description: description)
- }
-
-}
diff --git a/initializr-generator/src/test/groovy/io/spring/initializr/generator/ProjectGeneratorBuildTests.groovy b/initializr-generator/src/test/groovy/io/spring/initializr/generator/ProjectGeneratorBuildTests.groovy
deleted file mode 100644
index 992e563d..00000000
--- a/initializr-generator/src/test/groovy/io/spring/initializr/generator/ProjectGeneratorBuildTests.groovy
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Copyright 2012-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.
- * You may obtain a copy of the License at
- *
- * http://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
-
-import io.spring.initializr.metadata.BillOfMaterials
-import io.spring.initializr.metadata.Dependency
-import io.spring.initializr.test.metadata.InitializrMetadataTestBuilder
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
-
-import org.springframework.core.io.ClassPathResource
-
-/**
- * Project generator tests for supported build systems.
- *
- * @author Stephane Nicoll
- */
-@RunWith(Parameterized.class)
-class ProjectGeneratorBuildTests extends AbstractProjectGeneratorTests {
-
- @Parameterized.Parameters(name = "{0}")
- static Object[] parameters() {
- Object[] maven = ["maven", "pom.xml"]
- Object[] gradle = ["gradle", "build.gradle"]
- Object[] parameters = [maven, gradle]
- parameters
- }
-
- private final String build
- private final String fileName
- private final String assertFileName
-
- ProjectGeneratorBuildTests(String build, String fileName) {
- this.build = build
- this.fileName = fileName
- this.assertFileName = fileName + ".gen"
- }
-
- @Test
- void standardJarJava() {
- testStandardJar('java')
- }
-
- @Test
- void standardJarGroovy() {
- testStandardJar('groovy')
- }
-
- @Test
- void standardJarKotlin() {
- testStandardJar('kotlin')
- }
-
- private void testStandardJar(def language) {
- def request = createProjectRequest()
- request.language = language
- def project = generateProject(request)
- project.sourceCodeAssert("$fileName")
- .equalsTo(new ClassPathResource("project/$language/standard/$assertFileName"))
- }
-
- @Test
- void standardWarJava() {
- testStandardWar('java')
- }
-
- @Test
- void standardWarGroovy() {
- testStandardWar('java')
- }
-
- @Test
- void standardWarKotlin() {
- testStandardWar('kotlin')
- }
-
- private void testStandardWar(def language) {
- def request = createProjectRequest('web')
- request.packaging = 'war'
- request.language = language
- def project = generateProject(request)
- project.sourceCodeAssert("$fileName")
- .equalsTo(new ClassPathResource("project/$language/war/$assertFileName"))
- }
-
- @Test
- void versionOverride() {
- def request = createProjectRequest('web')
- request.buildProperties.versions['spring-foo.version'] = {'0.1.0.RELEASE'}
- request.buildProperties.versions['spring-bar.version'] = {'0.2.0.RELEASE'}
- def project = generateProject(request)
- project.sourceCodeAssert("$fileName")
- .equalsTo(new ClassPathResource("project/$build/version-override-$assertFileName"))
- }
-
- @Test
- void bomWithVersionProperty() {
- def foo = new Dependency(id: 'foo', groupId: 'org.acme', artifactId: 'foo', bom: 'the-bom')
- def bom = new BillOfMaterials(groupId: 'org.acme', artifactId: 'foo-bom',
- version: '1.3.3', versionProperty: 'foo.version')
- def metadata = InitializrMetadataTestBuilder.withDefaults()
- .addDependencyGroup('foo', foo)
- .addBom('the-bom', bom).build()
- applyMetadata(metadata)
- def request = createProjectRequest('foo')
- def project = generateProject(request)
- project.sourceCodeAssert("$fileName")
- .equalsTo(new ClassPathResource("project/$build/bom-property-$assertFileName"))
- }
-
- @Test
- void compileOnlyDependency() {
- def foo = new Dependency(id: 'foo', groupId: 'org.acme', artifactId: 'foo',
- scope: Dependency.SCOPE_COMPILE_ONLY)
- def metadata = InitializrMetadataTestBuilder.withDefaults()
- .addDependencyGroup('core', 'web', 'data-jpa')
- .addDependencyGroup('foo', foo)
- .build()
- applyMetadata(metadata)
- def request = createProjectRequest('foo', 'web', 'data-jpa')
- def project = generateProject(request)
- project.sourceCodeAssert("$fileName")
- .equalsTo(new ClassPathResource("project/$build/compile-only-dependency-$assertFileName"))
- }
-
- @Test
- void bomWithOrdering() {
- def foo = new Dependency(id: 'foo', groupId: 'org.acme', artifactId: 'foo', bom: 'foo-bom')
- def barBom = new BillOfMaterials(groupId: 'org.acme', artifactId: 'bar-bom',
- version: '1.0', order: 50)
- def bizBom = new BillOfMaterials(groupId: 'org.acme', artifactId: 'biz-bom',
- order: 40, additionalBoms: ['bar-bom'])
- bizBom.mappings << new BillOfMaterials.Mapping(versionRange: '1.0.0.RELEASE',
- version: '1.0')
- def fooBom = new BillOfMaterials(groupId: 'org.acme', artifactId: 'foo-bom',
- version: '1.0', order: 20, additionalBoms: ['biz-bom'])
-
- def metadata = InitializrMetadataTestBuilder.withDefaults()
- .addDependencyGroup('foo', foo)
- .addBom('foo-bom', fooBom)
- .addBom('bar-bom', barBom)
- .addBom('biz-bom', bizBom)
- .build()
- applyMetadata(metadata)
- def request = createProjectRequest('foo')
- def project = generateProject(request)
- project.sourceCodeAssert("$fileName")
- .equalsTo(new ClassPathResource("project/$build/bom-ordering-$assertFileName"))
- }
-
- @Override
- ProjectRequest createProjectRequest(String... styles) {
- def request = super.createProjectRequest(styles)
- request.type = "$build-project"
- request
- }
-
-}
diff --git a/initializr-generator/src/test/groovy/io/spring/initializr/generator/ProjectGeneratorLanguageTests.groovy b/initializr-generator/src/test/groovy/io/spring/initializr/generator/ProjectGeneratorLanguageTests.groovy
deleted file mode 100644
index 64c5c654..00000000
--- a/initializr-generator/src/test/groovy/io/spring/initializr/generator/ProjectGeneratorLanguageTests.groovy
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright 2012-2016 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
- *
- * http://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
-
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
-
-import org.springframework.core.io.ClassPathResource
-
-import static io.spring.initializr.test.generator.ProjectAssert.DEFAULT_APPLICATION_NAME
-import static io.spring.initializr.test.generator.ProjectAssert.DEFAULT_PACKAGE_NAME
-
-/**
- * Project generator tests for supported languages.
- *
- * @author Stephane Nicoll
- */
-@RunWith(Parameterized.class)
-class ProjectGeneratorLanguageTests extends AbstractProjectGeneratorTests {
-
- @Parameterized.Parameters(name = "{0}")
- static Object[] parameters() {
- Object[] java = ["java", "java"]
- Object[] groovy = ["groovy", "groovy"]
- Object[] kotlin = ["kotlin", "kt"]
- Object[] parameters = [java, groovy, kotlin]
- parameters
- }
-
- private final String language
- private final String extension
- private final String expectedExtension
-
- ProjectGeneratorLanguageTests(String language, String extension) {
- this.language = language
- this.extension = extension
- this.expectedExtension = extension + '.gen'
- }
-
- @Test
- void standardJar() {
- def request = createProjectRequest()
- request.language = language
- generateProject(request).isGenericProject(DEFAULT_PACKAGE_NAME, DEFAULT_APPLICATION_NAME,
- language, extension)
- }
-
- @Test
- void standardWar() {
- def request = createProjectRequest('web')
- request.language = language
- request.packaging = 'war'
- generateProject(request).isGenericWarProject(DEFAULT_PACKAGE_NAME, DEFAULT_APPLICATION_NAME,
- language, extension)
- }
-
- @Test
- void standardMainClass() {
- def request = createProjectRequest()
- request.language = language
-
- def project = generateProject(request)
- project.sourceCodeAssert("src/main/$language/com/example/DemoApplication.$extension")
- .equalsTo(new ClassPathResource("project/$language/standard/DemoApplication.$expectedExtension"))
- }
-
- @Test
- void standardTestClass() {
- def request = createProjectRequest()
- request.language = language
-
- def project = generateProject(request)
- project.sourceCodeAssert("src/test/$language/com/example/DemoApplicationTests.$extension")
- .equalsTo(new ClassPathResource("project/$language/standard/DemoApplicationTests.$expectedExtension"))
- }
-
- @Test
- void standardTestClassWeb() {
- def request = createProjectRequest('web')
- request.language = language
-
- def project = generateProject(request)
- project.sourceCodeAssert("src/test/$language/com/example/DemoApplicationTests.$extension")
- .equalsTo(new ClassPathResource("project/$language/standard/DemoApplicationTestsWeb.$expectedExtension"))
- }
-
- @Test
- void standardServletInitializer() {
- testServletInitializr(null, 'standard')
- }
-
- @Test
- void springBoot14M2ServletInitializer() {
- testServletInitializr('1.4.0.M2', 'standard')
- }
-
- @Test
- void springBoot14ServletInitializer() {
- testServletInitializr('1.4.0.M3', 'spring-boot-1.4')
- }
-
- private void testServletInitializr(String bootVersion, String expectedOutput) {
- def request = createProjectRequest()
- request.language = language
- request.packaging = 'war'
- if (bootVersion) {
- request.bootVersion = bootVersion
- }
- def project = generateProject(request)
- project.sourceCodeAssert("src/main/$language/com/example/ServletInitializer.$extension")
- .equalsTo(new ClassPathResource("project/$language/$expectedOutput/ServletInitializer.$expectedExtension"))
- }
-
- @Test
- void springBoot14M1TestClass() {
- def request = createProjectRequest()
- request.language = language
- request.bootVersion = '1.4.0.M1'
-
- def project = generateProject(request)
- project.sourceCodeAssert("src/test/$language/com/example/DemoApplicationTests.$extension")
- .equalsTo(new ClassPathResource("project/$language/standard/DemoApplicationTests.$expectedExtension"))
- }
-
- @Test
- void springBoot14TestClass() {
- def request = createProjectRequest()
- request.language = language
- request.bootVersion = '1.4.0.M2'
-
- def project = generateProject(request)
- project.sourceCodeAssert("src/test/$language/com/example/DemoApplicationTests.$extension")
- .equalsTo(new ClassPathResource("project/$language/spring-boot-1.4/DemoApplicationTests.$expectedExtension"))
- }
-
- @Test
- void springBoot14TestClassWeb() {
- def request = createProjectRequest('web')
- request.language = language
- request.bootVersion = '1.4.0.M2'
-
- def project = generateProject(request)
- project.sourceCodeAssert("src/test/$language/com/example/DemoApplicationTests.$extension")
- .equalsTo(new ClassPathResource("project/$language/spring-boot-1.4/DemoApplicationTests.$expectedExtension"))
- }
-
-}
diff --git a/initializr-generator/src/test/groovy/io/spring/initializr/generator/ProjectGeneratorTests.groovy b/initializr-generator/src/test/groovy/io/spring/initializr/generator/ProjectGeneratorTests.groovy
deleted file mode 100644
index 1874da0c..00000000
--- a/initializr-generator/src/test/groovy/io/spring/initializr/generator/ProjectGeneratorTests.groovy
+++ /dev/null
@@ -1,787 +0,0 @@
-/*
- * Copyright 2012-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.
- * You may obtain a copy of the License at
- *
- * http://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
-
-import io.spring.initializr.metadata.BillOfMaterials
-import io.spring.initializr.metadata.Dependency
-import io.spring.initializr.metadata.InitializrMetadata
-import io.spring.initializr.test.metadata.InitializrMetadataTestBuilder
-import org.junit.Rule
-import org.junit.Test
-import org.junit.rules.ExpectedException
-
-import org.springframework.boot.autoconfigure.EnableAutoConfiguration
-import org.springframework.boot.autoconfigure.SpringBootApplication
-import org.springframework.context.annotation.ComponentScan
-import org.springframework.context.annotation.Configuration
-import org.springframework.core.io.ClassPathResource
-
-import static org.hamcrest.CoreMatchers.containsString
-import static org.junit.Assert.assertThat
-import static org.junit.Assert.fail
-
-/**
- * Tests for {@link ProjectGenerator}
- *
- * @author Stephane Nicoll
- */
-class ProjectGeneratorTests extends AbstractProjectGeneratorTests {
-
- @Rule
- public final ExpectedException thrown = ExpectedException.none()
-
- @Test
- void defaultMavenPom() {
- def request = createProjectRequest('web')
- generateMavenPom(request).hasNoRepository()
- .hasSpringBootStarterDependency('web')
- verifyProjectSuccessfulEventFor(request)
- }
-
- @Test
- void defaultGradleBuild() {
- def request = createProjectRequest('web')
- generateGradleBuild(request)
- verifyProjectSuccessfulEventFor(request)
- }
-
- @Test
- void defaultProject() {
- def request = createProjectRequest('web')
- generateProject(request).isJavaProject().isMavenProject().pomAssert()
- .hasNoRepository().hasSpringBootStarterDependency('web')
- verifyProjectSuccessfulEventFor(request)
- }
-
- @Test
- void noDependencyAddsRootStarter() {
- def request = createProjectRequest()
- generateProject(request).isJavaProject().isMavenProject().pomAssert()
- .hasSpringBootStarterRootDependency()
- }
-
- @Test
- void mavenPomWithBootSnapshot() {
- def request = createProjectRequest('web')
- request.bootVersion = '1.0.1.BUILD-SNAPSHOT'
- generateMavenPom(request).hasSnapshotRepository()
- .hasSpringBootParent('1.0.1.BUILD-SNAPSHOT')
- .hasSpringBootStarterDependency('web')
- }
-
- @Test
- void mavenPomWithTarDependency() {
- def dependency = new Dependency(id: 'custom-artifact', groupId: 'org.foo', artifactId: 'custom-artifact', type: "tar.gz")
- def metadata = InitializrMetadataTestBuilder.withDefaults()
- .addDependencyGroup('test', dependency).build()
- applyMetadata(metadata)
-
- def request = createProjectRequest('custom-artifact')
- generateMavenPom(request).hasDependency(dependency)
- .hasDependenciesCount(2)
- }
-
- @Test
- void gradleBuildWithTarDependency() {
- def dependency = new Dependency(id: 'custom-artifact', groupId: 'org.foo', artifactId: 'custom-artifact', type: "tar.gz")
- def metadata = InitializrMetadataTestBuilder.withDefaults()
- .addDependencyGroup('test', dependency).build()
- applyMetadata(metadata)
-
- def request = createProjectRequest('custom-artifact')
- generateGradleBuild(request)
- .contains("compile('org.foo:custom-artifact@tar.gz')")
- }
-
- @Test
- void mavenPomWithWebFacet() {
- def dependency = new Dependency(id: 'thymeleaf', groupId: 'org.foo', artifactId: 'thymeleaf')
- dependency.facets << 'web'
- def metadata = InitializrMetadataTestBuilder.withDefaults()
- .addDependencyGroup('core', 'web', 'security', 'data-jpa')
- .addDependencyGroup('test', dependency).build()
- applyMetadata(metadata)
-
- def request = createProjectRequest('thymeleaf')
- generateMavenPom(request)
- .hasDependency('org.foo', 'thymeleaf')
- .hasDependenciesCount(2)
- }
-
- @Test
- void mavenWarWithWebFacet() {
- def dependency = new Dependency(id: 'thymeleaf', groupId: 'org.foo', artifactId: 'thymeleaf')
- dependency.facets << 'web'
- def metadata = InitializrMetadataTestBuilder.withDefaults()
- .addDependencyGroup('core', 'web', 'security', 'data-jpa')
- .addDependencyGroup('test', dependency).build()
- applyMetadata(metadata)
-
- def request = createProjectRequest('thymeleaf')
- request.packaging = 'war'
- generateProject(request).isJavaWarProject().isMavenProject().
- pomAssert()
- .hasSpringBootStarterTomcat()
- .hasDependency('org.foo', 'thymeleaf') // This is tagged as web facet so it brings the web one
- .hasSpringBootStarterTest()
- .hasDependenciesCount(3)
- }
-
- @Test
- void mavenWarPomWithoutWebFacet() {
- def request = createProjectRequest('data-jpa')
- request.packaging = 'war'
- generateMavenPom(request)
- .hasSpringBootStarterTomcat()
- .hasSpringBootStarterDependency('data-jpa')
- .hasSpringBootStarterDependency('web') // Added by war packaging
- .hasSpringBootStarterTest()
- .hasDependenciesCount(4)
- }
-
- @Test
- void gradleWarWithWebFacet() {
- def dependency = new Dependency(id: 'thymeleaf', groupId: 'org.foo', artifactId: 'thymeleaf')
- dependency.facets << 'web'
- def metadata = InitializrMetadataTestBuilder.withDefaults()
- .addDependencyGroup('core', 'web', 'security', 'data-jpa')
- .addDependencyGroup('test', dependency).build()
- applyMetadata(metadata)
-
- def request = createProjectRequest('thymeleaf')
- request.packaging = 'war'
- request.type = 'gradle-project'
- generateProject(request).isJavaWarProject().isGradleProject().
- gradleBuildAssert()
- .contains("compile('org.foo:thymeleaf')") // This is tagged as web facet so it brings the web one
- .doesNotContain("compile('org.springframework.boot:spring-boot-starter-web')")
- .contains("testCompile('org.springframework.boot:spring-boot-starter-test')")
- .contains("configurations {") // declare providedRuntime config
- .contains("providedRuntime")
- .contains("providedRuntime('org.springframework.boot:spring-boot-starter-tomcat')")
- }
-
- @Test
- void gradleWarPomWithoutWebFacet() {
- def request = createProjectRequest('data-jpa')
- request.packaging = 'war'
- generateGradleBuild(request)
- .contains("compile('org.springframework.boot:spring-boot-starter-data-jpa')")
- .contains("compile('org.springframework.boot:spring-boot-starter-web')") // Added by war packaging
- .contains("testCompile('org.springframework.boot:spring-boot-starter-test')")
- .contains("configurations {") // declare providedRuntime config
- .contains("providedRuntime")
- .contains("providedRuntime('org.springframework.boot:spring-boot-starter-tomcat')")
- }
-
- @Test
- void springBoot11UseEnableAutoConfigurationJava() {
- def request = createProjectRequest('web')
- request.bootVersion = '1.1.9.RELEASE'
- request.name = 'MyDemo'
- request.packageName = 'foo'
- generateProject(request).sourceCodeAssert('src/main/java/foo/MyDemoApplication.java')
- .hasImports(EnableAutoConfiguration.class.name, ComponentScan.class.name, Configuration.class.name)
- .doesNotHaveImports(SpringBootApplication.class.name)
- .contains('@EnableAutoConfiguration', '@Configuration', '@ComponentScan')
- .doesNotContain('@SpringBootApplication')
- }
-
- @Test
- void springBootUseSpringBootApplicationJava() {
- def request = createProjectRequest('web')
- request.bootVersion = '1.2.0.RC1'
- request.name = 'MyDemo'
- request.packageName = 'foo'
- generateProject(request).sourceCodeAssert('src/main/java/foo/MyDemoApplication.java')
- .hasImports(SpringBootApplication.class.name)
- .doesNotHaveImports(EnableAutoConfiguration.class.name, ComponentScan.class.name, Configuration.class.name)
- .contains('@SpringBootApplication')
- .doesNotContain('@EnableAutoConfiguration', '@Configuration', '@ComponentScan')
- }
-
- @Test
- void springBoot11UseEnableAutoConfigurationGroovy() {
- def request = createProjectRequest('web')
- request.language = 'groovy'
- request.bootVersion = '1.1.9.RELEASE'
- request.name = 'MyDemo'
- request.packageName = 'foo'
- generateProject(request).sourceCodeAssert('src/main/groovy/foo/MyDemoApplication.groovy')
- .hasImports(EnableAutoConfiguration.class.name, ComponentScan.class.name, Configuration.class.name)
- .doesNotHaveImports(SpringBootApplication.class.name)
- .contains('@EnableAutoConfiguration', '@Configuration', '@ComponentScan')
- .doesNotContain('@SpringBootApplication')
- }
-
- @Test
- void springBootUseSpringBootApplicationGroovy() {
- def request = createProjectRequest('web')
- request.language = 'groovy'
- request.bootVersion = '1.2.0.RC1'
- request.name = 'MyDemo'
- request.packageName = 'foo'
- generateProject(request).sourceCodeAssert('src/main/groovy/foo/MyDemoApplication.groovy')
- .hasImports(SpringBootApplication.class.name)
- .doesNotHaveImports(EnableAutoConfiguration.class.name, ComponentScan.class.name, Configuration.class.name)
- .contains('@SpringBootApplication')
- .doesNotContain('@EnableAutoConfiguration', '@Configuration', '@ComponentScan')
- }
-
- @Test
- void springBoot11UseEnableAutoConfigurationKotlin() {
- def request = createProjectRequest('web')
- request.language = 'kotlin'
- request.bootVersion = '1.1.9.RELEASE'
- request.name = 'MyDemo'
- request.packageName = 'foo'
- generateProject(request).sourceCodeAssert('src/main/kotlin/foo/MyDemoApplication.kt')
- .hasImports(EnableAutoConfiguration.class.name, ComponentScan.class.name, Configuration.class.name)
- .doesNotHaveImports(SpringBootApplication.class.name)
- .contains('@EnableAutoConfiguration', '@Configuration', '@ComponentScan')
- .doesNotContain('@SpringBootApplication')
- }
-
- @Test
- void springBootUseSpringBootApplicationKotlin() {
- def request = createProjectRequest('web')
- request.language = 'kotlin'
- request.bootVersion = '1.2.0.RC1'
- request.name = 'MyDemo'
- request.packageName = 'foo'
- generateProject(request).sourceCodeAssert('src/main/kotlin/foo/MyDemoApplication.kt')
- .hasImports(SpringBootApplication.class.name)
- .doesNotHaveImports(EnableAutoConfiguration.class.name, ComponentScan.class.name, Configuration.class.name)
- .contains('@SpringBootApplication')
- .doesNotContain('@EnableAutoConfiguration', '@Configuration', '@ComponentScan')
- }
-
- @Test
- void springBootUseGradle2() {
- def request = createProjectRequest('web')
- request.type = 'gradle-project'
- generateProject(request).isGradleProject('2.13')
- }
-
- @Test
- void springBoot2UseGradle3() {
- def request = createProjectRequest('web')
- request.type = 'gradle-project'
- request.bootVersion = '2.0.0.BUILD-SNAPSHOT'
- generateProject(request).isGradleProject('3.2.1')
- }
-
- @Test
- void customBaseDirectory() {
- def request = createProjectRequest()
- request.baseDir = 'my-project'
- generateProject(request).hasBaseDir('my-project')
- .isJavaProject()
- .isMavenProject()
- }
-
- @Test
- void customBaseDirectoryNested() {
- def request = createProjectRequest()
- request.baseDir = 'foo-bar/my-project'
- generateProject(request).hasBaseDir('foo-bar/my-project')
- .isJavaProject()
- .isMavenProject()
- }
-
- @Test
- void groovyWithMavenUsesGroovyDir() {
- def request = createProjectRequest('web')
- request.type = 'maven-project'
- request.language = 'groovy'
- generateProject(request).isMavenProject().isGroovyProject()
- }
-
- @Test
- void groovyWithGradleUsesGroovyDir() {
- def request = createProjectRequest('web')
- request.type = 'gradle-project'
- request.language = 'groovy'
- generateProject(request).isGradleProject().isGroovyProject()
- }
-
- @Test
- void mavenPomWithCustomVersion() {
- def whatever = new Dependency(id: 'whatever', groupId: 'org.acme', artifactId: 'whatever', version: '1.2.3')
- def metadata = InitializrMetadataTestBuilder.withDefaults()
- .addDependencyGroup('core', 'web', 'security', 'data-jpa')
- .addDependencyGroup('foo', whatever).build()
- applyMetadata(metadata)
- def request = createProjectRequest('whatever', 'data-jpa', 'web')
- generateMavenPom(request).hasDependency(whatever)
- .hasSpringBootStarterDependency('data-jpa')
- .hasSpringBootStarterDependency('web')
- }
-
- @Test
- void defaultMavenPomHasSpringBootParent() {
- def request = createProjectRequest('web')
- generateMavenPom(request).hasSpringBootParent(request.bootVersion)
- }
-
- @Test
- void mavenPomWithCustomParentPom() {
- def metadata = InitializrMetadataTestBuilder.withDefaults()
- .addDependencyGroup('core', 'web', 'security', 'data-jpa')
- .setMavenParent('com.foo', 'foo-parent', '1.0.0-SNAPSHOT', false)
- .build()
- applyMetadata(metadata)
- def request = createProjectRequest('web')
- generateMavenPom(request)
- .hasParent('com.foo', 'foo-parent', '1.0.0-SNAPSHOT')
- .hasBomsCount(0)
- }
-
- @Test
- void mavenPomWithCustomParentPomAndSpringBootBom() {
- def metadata = InitializrMetadataTestBuilder.withDefaults()
- .addDependencyGroup('core', 'web', 'security', 'data-jpa')
- .setMavenParent('com.foo', 'foo-parent', '1.0.0-SNAPSHOT', true)
- .build()
- applyMetadata(metadata)
- def request = createProjectRequest('web')
- request.bootVersion = '1.0.2.RELEASE'
- generateMavenPom(request)
- .hasParent('com.foo', 'foo-parent', '1.0.0-SNAPSHOT')
- .hasProperty('spring-boot.version', '1.0.2.RELEASE')
- .hasBom('org.springframework.boot', 'spring-boot-dependencies', '${spring-boot.version}')
- .hasBomsCount(1)
- }
-
- @Test
- void gradleBuildWithCustomParentPomAndSpringBootBom() {
- def metadata = InitializrMetadataTestBuilder.withDefaults()
- .addDependencyGroup('core', 'web', 'security', 'data-jpa')
- .setMavenParent('com.foo', 'foo-parent', '1.0.0-SNAPSHOT', true)
- .build()
- applyMetadata(metadata)
- def request = createProjectRequest('web')
- request.bootVersion = '1.0.2.RELEASE'
- generateGradleBuild(request)
- .doesNotContain("ext['spring-boot.version'] = '1.0.2.RELEASE'")
- .doesNotContain("mavenBom \"org.springframework.boot:spring-boot-dependencies:1.0.2.RELEASE\"")
- }
-
- @Test
- void gradleBuildWithBootSnapshot() {
- def request = createProjectRequest('web')
- request.bootVersion = '1.0.1.BUILD-SNAPSHOT'
- generateGradleBuild(request).hasSnapshotRepository()
- }
-
- @Test
- void gradleBuildWithCustomVersion() {
- def whatever = new Dependency(id: 'whatever', groupId: 'org.acme', artifactId: 'whatever', version: '1.2.3')
- def metadata = InitializrMetadataTestBuilder.withDefaults()
- .addDependencyGroup('core', 'web', 'security', 'data-jpa')
- .addDependencyGroup('foo', whatever).build()
- applyMetadata(metadata)
- def request = createProjectRequest('whatever', 'data-jpa', 'web')
- generateGradleBuild(request)
- .contains("compile('org.springframework.boot:spring-boot-starter-web')")
- .contains("compile('org.springframework.boot:spring-boot-starter-data-jpa')")
- .contains("compile('org.acme:whatever:1.2.3')")
- }
-
- @Test
- void mavenPomWithCustomScope() {
- def h2 = new Dependency(id: 'h2', groupId: 'org.h2', artifactId: 'h2', scope: 'runtime')
- def hamcrest = new Dependency(id: 'hamcrest', groupId: 'org.hamcrest',
- artifactId: 'hamcrest', scope: 'test')
- def servlet = new Dependency(id: 'servlet-api', groupId: 'javax.servlet',
- artifactId: 'servlet-api', scope: 'provided')
- def metadata = InitializrMetadataTestBuilder.withDefaults()
- .addDependencyGroup('core', 'web', 'security', 'data-jpa')
- .addDependencyGroup('database', h2)
- .addDependencyGroup('container', servlet)
- .addDependencyGroup('test', hamcrest).build()
- applyMetadata(metadata)
- def request = createProjectRequest('hamcrest', 'h2', 'servlet-api', 'data-jpa', 'web')
- generateMavenPom(request).hasDependency(h2).hasDependency(hamcrest).hasDependency(servlet)
- .hasSpringBootStarterDependency('data-jpa')
- .hasSpringBootStarterDependency('web')
- }
-
- @Test
- void gradleBuildWithCustomScope() {
- def h2 = new Dependency(id: 'h2', groupId: 'org.h2', artifactId: 'h2', scope: 'runtime')
- def hamcrest = new Dependency(id: 'hamcrest', groupId: 'org.hamcrest',
- artifactId: 'hamcrest', scope: 'test')
- def servlet = new Dependency(id: 'servlet-api', groupId: 'javax.servlet',
- artifactId: 'servlet-api', scope: 'provided')
- def metadata = InitializrMetadataTestBuilder.withDefaults()
- .addDependencyGroup('core', 'web', 'security', 'data-jpa')
- .addDependencyGroup('database', h2)
- .addDependencyGroup('container', servlet)
- .addDependencyGroup('test', hamcrest).build()
- applyMetadata(metadata)
- def request = createProjectRequest('hamcrest', 'h2', 'servlet-api', 'data-jpa', 'web')
- generateGradleBuild(request)
- .contains("compile('org.springframework.boot:spring-boot-starter-web')")
- .contains("compile('org.springframework.boot:spring-boot-starter-data-jpa')")
- .contains("runtime('org.h2:h2')")
- .contains("configurations {") // declare providedRuntime config
- .contains("providedRuntime")
- .contains("providedRuntime('javax.servlet:servlet-api')")
- .contains("testCompile('org.hamcrest:hamcrest')")
- }
-
- @Test
- void gradleBuildBeforeWithSpringBoot13() {
- def metadata = InitializrMetadataTestBuilder.withDefaults()
- .addDependencyGroup('core', 'web', 'jpa')
- .setGradleEnv('0.5.9.RELEASE').build()
- applyMetadata(metadata)
- def request = createProjectRequest('web')
- request.bootVersion = '1.2.3.RELEASE'
- generateGradleBuild(request)
- .contains("springBootVersion = '1.2.3.RELEASE'")
- .contains("classpath('io.spring.gradle:dependency-management-plugin:0.5.9.RELEASE')")
- .contains("apply plugin: 'spring-boot'")
- .contains("apply plugin: 'io.spring.dependency-management'")
- }
-
- @Test
- void gradleBuildAsFromSpringBoot13() {
- def metadata = InitializrMetadataTestBuilder.withDefaults()
- .addDependencyGroup('core', 'web', 'jpa')
- .setGradleEnv('0.5.9.RELEASE').build()
- applyMetadata(metadata)
- def request = createProjectRequest('web')
- request.bootVersion = '1.3.0.BUILD-SNAPSHOT'
- generateGradleBuild(request)
- .contains("springBootVersion = '1.3.0.BUILD-SNAPSHOT'")
- .contains("apply plugin: 'spring-boot'")
- .doesNotContain("classpath('io.spring.gradle:dependency-management-plugin:0.5.9.RELEASE')")
- .doesNotContain("apply plugin: 'io.spring.dependency-management'")
- }
-
- @Test
- void gradleBuildAsFromSpringBoot142() {
- def request = createProjectRequest('web')
- request.bootVersion = '1.4.2.BUILD-SNAPSHOT'
- generateGradleBuild(request)
- .contains("springBootVersion = '1.4.2.BUILD-SNAPSHOT'")
- .contains("apply plugin: 'org.springframework.boot'")
- .doesNotContain("apply plugin: 'spring-boot'")
- }
-
- @Test
- void mavenBom() {
- def foo = new Dependency(id: 'foo', groupId: 'org.acme', artifactId: 'foo', bom: 'foo-bom')
- def metadata = InitializrMetadataTestBuilder.withDefaults()
- .addDependencyGroup('foo', foo)
- .addBom('foo-bom', 'org.acme', 'foo-bom', '1.2.3').build()
- applyMetadata(metadata)
- def request = createProjectRequest('foo')
- generateMavenPom(request).hasDependency(foo)
- .hasBom('org.acme', 'foo-bom', '1.2.3')
- }
-
- @Test
- void mavenBomWithSeveralDependenciesOnSameBom() {
- def foo = new Dependency(id: 'foo', groupId: 'org.acme', artifactId: 'foo', bom: 'the-bom')
- def bar = new Dependency(id: 'bar', groupId: 'org.acme', artifactId: 'bar', bom: 'the-bom')
- def metadata = InitializrMetadataTestBuilder.withDefaults()
- .addDependencyGroup('group', foo, bar)
- .addBom('the-bom', 'org.acme', 'the-bom', '1.2.3').build()
- applyMetadata(metadata)
- def request = createProjectRequest('foo', 'bar')
- generateMavenPom(request).hasDependency(foo)
- .hasBom('org.acme', 'the-bom', '1.2.3')
- .hasBomsCount(1)
- }
-
- @Test
- void mavenBomWithVersionMapping() {
- def foo = new Dependency(id: 'foo', groupId: 'org.acme', artifactId: 'foo', bom: 'the-bom')
- def bom = new BillOfMaterials(groupId: 'org.acme', artifactId: 'foo-bom')
- bom.mappings << new BillOfMaterials.Mapping(versionRange: '[1.2.0.RELEASE,1.3.0.M1)', version: '1.0.0')
- bom.mappings << new BillOfMaterials.Mapping(versionRange: '1.3.0.M1', version: '1.2.0')
- def metadata = InitializrMetadataTestBuilder.withDefaults()
- .addDependencyGroup('foo', foo)
- .addBom('the-bom', bom).build()
- applyMetadata(metadata)
-
- // First version
- def request = createProjectRequest('foo')
- request.bootVersion = '1.2.5.RELEASE'
- generateMavenPom(request).hasDependency(foo)
- .hasSpringBootParent('1.2.5.RELEASE')
- .hasBom('org.acme', 'foo-bom', '1.0.0')
-
- // Second version
- def request2 = createProjectRequest('foo')
- request2.bootVersion = '1.3.0.M1'
- generateMavenPom(request2).hasDependency(foo)
- .hasSpringBootParent('1.3.0.M1')
- .hasBom('org.acme', 'foo-bom', '1.2.0')
- }
-
- @Test
- void mavenBomWithVersionMappingAndExtraRepositories() {
- def foo = new Dependency(id: 'foo', groupId: 'org.acme', artifactId: 'foo', bom: 'the-bom')
- def bom = new BillOfMaterials(groupId: 'org.acme', artifactId: 'foo-bom', repositories: ['foo-repo'])
- bom.mappings << new BillOfMaterials.Mapping(versionRange: '[1.2.0.RELEASE,1.3.0.M1)', version: '1.0.0')
- bom.mappings << new BillOfMaterials.Mapping(versionRange: '1.3.0.M1', version: '1.2.0', repositories: ['foo-repo', 'bar-repo'])
- def metadata = InitializrMetadataTestBuilder.withDefaults()
- .addDependencyGroup('foo', foo)
- .addBom('the-bom', bom)
- .addRepository('foo-repo', 'repo', 'http://example.com/foo', true)
- .addRepository('bar-repo', 'repo', 'http://example.com/bar', false).build()
- applyMetadata(metadata)
-
- // Second version
- def request = createProjectRequest('foo')
- request.bootVersion = '1.3.0.RELEASE'
- generateMavenPom(request).hasDependency(foo)
- .hasSpringBootParent('1.3.0.RELEASE')
- .hasBom('org.acme', 'foo-bom', '1.2.0')
- .hasRepository('foo-repo', 'repo', 'http://example.com/foo', true)
- .hasRepository('bar-repo', 'repo', 'http://example.com/bar', false)
- .hasRepositoriesCount(2)
- }
-
- @Test
- void gradleBom() {
- def foo = new Dependency(id: 'foo', groupId: 'org.acme', artifactId: 'foo', bom: 'foo-bom')
- def metadata = InitializrMetadataTestBuilder.withDefaults()
- .addDependencyGroup('foo', foo)
- .addBom('foo-bom', 'org.acme', 'foo-bom', '1.2.3').build()
- applyMetadata(metadata)
- def request = createProjectRequest('foo')
- generateGradleBuild(request)
- .contains("dependencyManagement {")
- .contains("imports {")
- .contains("mavenBom \"org.acme:foo-bom:1.2.3\"")
- }
-
- @Test
- void mavenRepository() {
- def foo = new Dependency(id: 'foo', groupId: 'org.acme', artifactId: 'foo', repository: 'foo-repo')
- def metadata = InitializrMetadataTestBuilder.withDefaults()
- .addDependencyGroup('foo', foo)
- .addRepository('foo-repo', 'foo', 'http://example.com/repo', false).build()
- applyMetadata(metadata)
- def request = createProjectRequest('foo')
- generateMavenPom(request).hasDependency(foo)
- .hasRepository('foo-repo', 'foo', 'http://example.com/repo', false)
- }
-
- @Test
- void mavenRepositoryWithSeveralDependenciesOnSameRepository() {
- def foo = new Dependency(id: 'foo', groupId: 'org.acme', artifactId: 'foo', repository: 'the-repo')
- def bar = new Dependency(id: 'bar', groupId: 'org.acme', artifactId: 'bar', repository: 'the-repo')
- def metadata = InitializrMetadataTestBuilder.withDefaults()
- .addDependencyGroup('group', foo, bar)
- .addRepository('the-repo', 'repo', 'http://example.com/repo', true).build()
- applyMetadata(metadata)
- def request = createProjectRequest('foo', 'bar')
- generateMavenPom(request).hasDependency(foo)
- .hasRepository('the-repo', 'repo', 'http://example.com/repo', true)
- .hasRepositoriesCount(1)
- }
-
- @Test
- void gradleRepository() {
- def foo = new Dependency(id: 'foo', groupId: 'org.acme', artifactId: 'foo', repository: 'foo-repo')
- def metadata = InitializrMetadataTestBuilder.withDefaults()
- .addDependencyGroup('foo', foo)
- .addRepository('foo-repo', 'foo', 'http://example.com/repo', false).build()
- applyMetadata(metadata)
- def request = createProjectRequest('foo')
- generateGradleBuild(request)
- .hasRepository('http://example.com/repo')
- }
-
- @Test
- void projectWithOnlyStarterDependency() {
- def foo = new Dependency(id: 'foo', groupId: 'org.foo', artifactId: 'custom-my-starter')
- def metadata = InitializrMetadataTestBuilder.withDefaults()
- .addDependencyGroup('foo', foo).build()
- applyMetadata(metadata)
-
- def request = createProjectRequest('foo')
- generateMavenPom(request)
- .hasDependency('org.foo', 'custom-my-starter')
- .hasSpringBootStarterTest()
- .hasDependenciesCount(2)
- }
-
- @Test
- void projectWithOnlyNonStarterDependency() {
- def foo = new Dependency(id: 'foo', groupId: 'org.foo', artifactId: 'foo')
- foo.starter = false
- def metadata = InitializrMetadataTestBuilder.withDefaults()
- .addDependencyGroup('foo', foo).build()
- applyMetadata(metadata)
-
- def request = createProjectRequest('foo')
- generateMavenPom(request)
- .hasDependency('org.foo', 'foo')
- .hasSpringBootStarterRootDependency()
- .hasSpringBootStarterTest()
- .hasDependenciesCount(3)
- }
-
- @Test
- void buildPropertiesMaven() {
- def request = createProjectRequest('web')
- request.buildProperties.maven['name'] = { 'test' }
- request.buildProperties.versions['foo.version'] = { '1.2.3' }
- request.buildProperties.gradle['ignore.property'] = { 'yes' }
-
- generateMavenPom(request)
- .hasProperty('name', 'test')
- .hasProperty('foo.version', '1.2.3')
- .hasNoProperty('ignore.property')
- }
-
- @Test
- void buildPropertiesGradle() {
- def request = createProjectRequest('web')
- request.buildProperties.gradle['name'] = { 'test' }
- request.buildProperties.versions['foo.version'] = { '1.2.3' }
- request.buildProperties.maven['ignore.property'] = { 'yes' }
-
- generateGradleBuild(request)
- .contains("name = 'test'")
- .contains("ext['foo.version'] = '1.2.3'")
- .doesNotContain('ignore.property')
- }
-
- @Test
- void versionRangeWithPostProcessor() {
- Dependency foo = new Dependency(id: 'foo', groupId: 'org.acme', artifactId: 'foo')
- foo.mappings << new Dependency.Mapping(versionRange: '[1.2.0.RELEASE,1.3.0.M1)', version: '1.0.0')
- foo.mappings << new Dependency.Mapping(versionRange: '1.3.0.M1', version: '1.2.0')
- def metadata = InitializrMetadataTestBuilder.withDefaults()
- .addDependencyGroup('foo', foo).build()
- applyMetadata(metadata)
-
- // First without processor, get the correct version
- def request = createProjectRequest('foo')
- request.bootVersion = '1.2.5.RELEASE'
- generateMavenPom(request).hasDependency(
- new Dependency(id: 'foo', groupId: 'org.acme', artifactId: 'foo', version: '1.0.0'))
-
- // First after processor that flips Spring Boot version
- projectGenerator.requestResolver = new ProjectRequestResolver(Collections.singletonList(
- new ProjectRequestPostProcessorAdapter() {
- @Override
- void postProcessBeforeResolution(ProjectRequest r, InitializrMetadata m) {
- r.bootVersion = '1.3.0.M2'
- }
- }
- ))
- generateMavenPom(request).hasDependency(
- new Dependency(id: 'foo', groupId: 'org.acme', artifactId: 'foo', version: '1.2.0'))
- }
-
- @Test
- void gitIgnoreMaven() {
- def request = createProjectRequest()
- request.type = 'maven-project'
- def project = generateProject(request)
- project.sourceCodeAssert(".gitignore")
- .equalsTo(new ClassPathResource("project/maven/gitignore.gen"))
- }
-
- @Test
- void gitIgnoreGradle() {
- def request = createProjectRequest()
- request.type = 'gradle-project'
- def project = generateProject(request)
- project.sourceCodeAssert(".gitignore")
- .equalsTo(new ClassPathResource("project/gradle/gitignore.gen"))
- }
-
- @Test
- void invalidProjectTypeMavenPom() {
- def request = createProjectRequest('web')
- request.type = 'gradle-build'
- this.thrown.expect(InvalidProjectRequestException)
- this.thrown.expectMessage('gradle-build')
- projectGenerator.generateMavenPom(request)
- }
-
- @Test
- void invalidProjectTypeGradleBuild() {
- def request = createProjectRequest('web')
- request.type = 'maven-build'
- this.thrown.expect(InvalidProjectRequestException)
- this.thrown.expectMessage('maven-build')
- projectGenerator.generateGradleBuild(request)
- }
-
- @Test
- void invalidDependency() {
- def request = createProjectRequest('foo-bar')
- try {
- generateMavenPom(request)
- fail("Should have failed to generate project")
- } catch (InvalidProjectRequestException ex) {
- assertThat ex.message, containsString('foo-bar')
- verifyProjectFailedEventFor(request, ex)
- }
- }
-
- @Test
- void invalidType() {
- def request = createProjectRequest('web')
- request.type = 'foo-bar'
- try {
- generateProject(request)
- fail("Should have failed to generate project")
- } catch (InvalidProjectRequestException ex) {
- assertThat ex.message, containsString('foo-bar')
- verifyProjectFailedEventFor(request, ex)
- }
- }
-
- @Test
- void invalidPackaging() {
- def request = createProjectRequest('web')
- request.packaging = 'foo-bar'
- try {
- generateGradleBuild(request)
- fail("Should have failed to generate project")
- } catch (InvalidProjectRequestException ex) {
- assertThat ex.message, containsString('foo-bar')
- verifyProjectFailedEventFor(request, ex)
- }
- }
-
- @Test
- void invalidLanguage() {
- def request = createProjectRequest('web')
- request.language = 'foo-bar'
- try {
- generateProject(request)
- fail("Should have failed to generate project")
- } catch (InvalidProjectRequestException ex) {
- assertThat ex.message, containsString('foo-bar')
- verifyProjectFailedEventFor(request, ex)
- }
- }
-
-}
diff --git a/initializr-generator/src/test/groovy/io/spring/initializr/generator/ProjectRequestResolverTests.groovy b/initializr-generator/src/test/groovy/io/spring/initializr/generator/ProjectRequestResolverTests.groovy
deleted file mode 100644
index 1a6be5b1..00000000
--- a/initializr-generator/src/test/groovy/io/spring/initializr/generator/ProjectRequestResolverTests.groovy
+++ /dev/null
@@ -1,86 +0,0 @@
-package io.spring.initializr.generator
-
-import io.spring.initializr.metadata.InitializrMetadata
-import io.spring.initializr.test.metadata.InitializrMetadataTestBuilder
-import org.junit.Before
-import org.junit.Test
-
-import static org.junit.Assert.assertEquals
-
-/**
- * Tests for {@link ProjectRequestResolver}.
- *
- * @author Stephane Nicoll
- */
-class ProjectRequestResolverTests {
-
- def metadata = InitializrMetadataTestBuilder.withDefaults()
- .addDependencyGroup('test', 'web', 'security', 'data-jpa')
- .build()
-
- final List postProcessors = []
- final GenericProjectRequestPostProcessor processor = new GenericProjectRequestPostProcessor()
-
- @Before
- void setup() {
- this.postProcessors << processor
- }
-
- @Test
- void beforeResolution() {
- processor.before['javaVersion'] = '1.2'
- ProjectRequest request = resolve(createMavenProjectRequest(), postProcessors)
- assertEquals '1.2', request.javaVersion
- assertEquals '1.2', request.buildProperties.versions['java.version'].call()
- }
-
- @Test
- void afterResolution() {
- postProcessors << new ProjectRequestPostProcessorAdapter() {
- @Override
- void postProcessAfterResolution(ProjectRequest request, InitializrMetadata metadata) {
- request.buildProperties.maven.clear()
- request.buildProperties.maven['foo'] = { 'bar' }
- }
- }
- ProjectRequest request = resolve(createMavenProjectRequest(), postProcessors)
- assertEquals 1, request.buildProperties.maven.size()
- assertEquals 'bar', request.buildProperties.maven['foo'].call()
- }
-
- ProjectRequest resolve(def request, def processors) {
- new ProjectRequestResolver(processors)
- .resolve(request, metadata)
- }
-
- ProjectRequest createMavenProjectRequest(String... styles) {
- def request = createProjectRequest(styles)
- request.type = 'maven-project'
- request
- }
-
- ProjectRequest createProjectRequest(String... styles) {
- def request = new ProjectRequest()
- request.initialize(metadata)
- request.style.addAll Arrays.asList(styles)
- request
- }
-
- static class GenericProjectRequestPostProcessor implements ProjectRequestPostProcessor {
-
- final Map before = [:]
- final Map after = [:]
-
- @Override
- void postProcessBeforeResolution(ProjectRequest request, InitializrMetadata metadata) {
- before.forEach { k, v -> request.setProperty(k, v) }
- }
-
- @Override
- void postProcessAfterResolution(ProjectRequest request, InitializrMetadata metadata) {
- after.forEach { k, v -> request.setProperty(k, v) }
- }
-
- }
-
-}
diff --git a/initializr-generator/src/test/groovy/io/spring/initializr/generator/ProjectRequestTests.groovy b/initializr-generator/src/test/groovy/io/spring/initializr/generator/ProjectRequestTests.groovy
deleted file mode 100644
index 55f7779a..00000000
--- a/initializr-generator/src/test/groovy/io/spring/initializr/generator/ProjectRequestTests.groovy
+++ /dev/null
@@ -1,375 +0,0 @@
-/*
- * Copyright 2012-2016 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
- *
- * http://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
-
-import io.spring.initializr.metadata.BillOfMaterials
-import io.spring.initializr.metadata.Dependency
-import io.spring.initializr.metadata.InitializrMetadataBuilder
-import io.spring.initializr.test.metadata.InitializrMetadataTestBuilder
-import org.junit.Rule
-import org.junit.Test
-import org.junit.rules.ExpectedException
-
-import static org.junit.Assert.assertEquals
-import static org.junit.Assert.assertNull
-
-/**
- * @author Stephane Nicoll
- */
-class ProjectRequestTests {
-
- @Rule
- public final ExpectedException thrown = ExpectedException.none()
-
- @Test
- void initializeProjectRequest() {
- def metadata = InitializrMetadataBuilder.create().build()
- metadata.groupId.content = 'org.acme'
- metadata.artifactId.content = 'my-project'
- ProjectRequest request = new ProjectRequest()
- request.initialize(metadata)
- assertEquals 'org.acme', request.groupId
- assertEquals 'my-project', request.artifactId
- }
-
- @Test
- void initializeProjectRequestWithDefaults() {
- def metadata = InitializrMetadataTestBuilder.withDefaults().build()
- ProjectRequest request = new ProjectRequest()
- request.initialize(metadata)
- assertEquals metadata.name.content, request.name
- assertEquals metadata.types.default.id, request.type
- assertEquals metadata.description.content, request.description
- assertEquals metadata.groupId.content, request.groupId
- assertEquals metadata.artifactId.content, request.artifactId
- assertEquals metadata.version.content, request.version
- assertEquals metadata.bootVersions.default.id, request.bootVersion
- assertEquals metadata.packagings.default.id, request.packaging
- }
-
- @Test
- void resolve() {
- def request = new ProjectRequest()
- def metadata = InitializrMetadataTestBuilder.withDefaults()
- .addDependencyGroup('code', 'web', 'security', 'spring-data').build()
-
- request.type = 'maven-project'
- request.style << 'web' << 'spring-data'
- request.resolve(metadata)
- assertEquals 'Build type not detected', 'maven', request.build
- assertBootStarter(request.resolvedDependencies[0], 'web')
- assertBootStarter(request.resolvedDependencies[1], 'spring-data')
- }
-
- @Test
- void resolveWithDependencies() {
- def request = new ProjectRequest()
- def metadata = InitializrMetadataTestBuilder.withDefaults()
- .addDependencyGroup('code', 'web', 'security', 'spring-data').build()
-
- request.type = 'maven-project'
- request.dependencies << 'web' << 'spring-data'
- request.resolve(metadata)
- assertEquals 'Build type not detected', 'maven', request.build
- assertBootStarter(request.resolvedDependencies[0], 'web')
- assertBootStarter(request.resolvedDependencies[1], 'spring-data')
- }
-
- @Test
- void resolveFullMetadata() {
- def request = new ProjectRequest()
- def metadata = InitializrMetadataTestBuilder.withDefaults()
- .addDependencyGroup('code', createDependency('org.foo', 'acme', '1.2.0')).build()
- request.style << 'org.foo:acme'
- request.resolve(metadata)
- assertDependency(request.resolvedDependencies[0], 'org.foo', 'acme', '1.2.0')
- }
-
- @Test
- void resolveUnknownSimpleId() {
- def request = new ProjectRequest()
- def metadata = InitializrMetadataTestBuilder.withDefaults()
- .addDependencyGroup('code', 'org.foo:bar').build()
-
- request.style << 'org.foo:bar' << 'foo-bar'
-
- thrown.expect(InvalidProjectRequestException)
- thrown.expectMessage('foo-bar')
- request.resolve(metadata)
- assertEquals(1, request.resolvedDependencies.size())
- }
-
- @Test
- void resolveUnknownDependency() {
- def request = new ProjectRequest()
- def metadata = InitializrMetadataTestBuilder.withDefaults()
- .addDependencyGroup('code', 'org.foo:bar').build()
-
- request.style << 'org.foo:acme' // does not exist
-
- thrown.expect(InvalidProjectRequestException)
- thrown.expectMessage('org.foo:acme')
- request.resolve(metadata)
- assertEquals(1, request.resolvedDependencies.size())
- }
-
- @Test
- void resolveDependencyInRange() {
- def request = new ProjectRequest()
- def dependency = createDependency('org.foo', 'bar', '1.2.0.RELEASE')
- dependency.versionRange = '[1.0.1.RELEASE, 1.2.0.RELEASE)'
- def metadata = InitializrMetadataTestBuilder.withDefaults()
- .addDependencyGroup('code', dependency).build()
-
- request.style << 'org.foo:bar'
- request.bootVersion = '1.1.2.RELEASE'
- request.resolve(metadata)
- }
-
- @Test
- void resolveDependencyNotInRange() {
- def request = new ProjectRequest()
- def dependency = createDependency('org.foo', 'bar', '1.2.0.RELEASE')
- dependency.versionRange = '[1.0.1.RELEASE, 1.2.0.RELEASE)'
- def metadata = InitializrMetadataTestBuilder.withDefaults()
- .addDependencyGroup('code', dependency).build()
-
- request.style << 'org.foo:bar'
- request.bootVersion = '0.9.9.RELEASE'
-
- thrown.expect(InvalidProjectRequestException)
- thrown.expectMessage('org.foo:bar')
- thrown.expectMessage('0.9.9.RELEASE')
- request.resolve(metadata)
- }
-
- @Test
- void resolveDependencyVersion() {
- def dependency = createDependency('org.foo', 'bar', '1.2.0.RELEASE')
- dependency.mappings << new Dependency.Mapping(
- version: '0.1.0.RELEASE', versionRange: '[1.0.0.RELEASE, 1.1.0.RELEASE)')
- dependency.mappings << new Dependency.Mapping(
- version: '0.2.0.RELEASE', versionRange: '1.1.0.RELEASE')
- def metadata = InitializrMetadataTestBuilder.withDefaults()
- .addDependencyGroup('code', dependency).build()
-
- def request = new ProjectRequest()
- request.bootVersion = '1.0.5.RELEASE'
- request.style << 'org.foo:bar'
- request.resolve(metadata)
- assertDependency(request.resolvedDependencies[0], 'org.foo', 'bar', '0.1.0.RELEASE')
-
- def anotherRequest = new ProjectRequest()
- anotherRequest.bootVersion = '1.1.0.RELEASE'
- anotherRequest.style << 'org.foo:bar'
- anotherRequest.resolve(metadata)
- assertDependency(anotherRequest.resolvedDependencies[0], 'org.foo', 'bar', '0.2.0.RELEASE')
- }
-
- @Test
- void resolveBuild() {
- def request = new ProjectRequest()
- def metadata = InitializrMetadataTestBuilder.withDefaults().build()
- request.type = 'gradle-project'
-
- request.resolve(metadata)
- assertEquals 'gradle', request.build
- }
-
- @Test
- void resolveBuildNoTag() {
- def request = new ProjectRequest()
- def metadata = InitializrMetadataTestBuilder.withDefaults()
- .addType('foo', false, '/foo.zip', null, null).build()
- request.type = 'foo'
-
- request.resolve(metadata)
- assertNull request.build
- }
-
- @Test
- void resolveUnknownType() {
- def request = new ProjectRequest()
- def metadata = InitializrMetadataTestBuilder.withDefaults().build()
- request.type = 'foo-project'
-
- thrown.expect(InvalidProjectRequestException)
- thrown.expectMessage('foo-project')
- request.resolve(metadata)
- }
-
- @Test
- void resolveApplicationNameWithNoName() {
- def request = new ProjectRequest()
- def metadata = InitializrMetadataTestBuilder.withDefaults().build()
-
- request.resolve(metadata)
- assertEquals metadata.configuration.env.fallbackApplicationName, request.applicationName
- }
-
- @Test
- void resolveApplicationName() {
- def request = new ProjectRequest()
- request.name = 'Foo2'
- def metadata = InitializrMetadataTestBuilder.withDefaults().build()
-
- request.resolve(metadata)
- assertEquals 'Foo2Application', request.applicationName
- }
-
- @Test
- void resolveApplicationNameWithApplicationNameSet() {
- def request = new ProjectRequest()
- request.name = 'Foo2'
- request.applicationName = 'MyApplicationName'
- def metadata = InitializrMetadataTestBuilder.withDefaults().build()
-
- request.resolve(metadata)
- assertEquals 'MyApplicationName', request.applicationName
- }
-
- @Test
- void cleanPackageNameWithNoName() {
- def request = new ProjectRequest()
- def metadata = InitializrMetadataTestBuilder.withDefaults().build()
-
- request.resolve(metadata)
- assertEquals metadata.packageName.content, request.packageName
- }
-
- @Test
- void cleanPackageName() {
- def request = new ProjectRequest()
- request.packageName = 'com:foo bar'
- def metadata = InitializrMetadataTestBuilder.withDefaults().build()
-
- request.resolve(metadata)
- assertEquals 'com.foo.bar', request.packageName
- }
-
- @Test
- void resolveAdditionalBoms() {
- def request = new ProjectRequest()
- def dependency = new Dependency(id: 'foo', bom: 'foo-bom')
- def bom = new BillOfMaterials(groupId: 'com.example', artifactId: 'foo-bom',
- version: '1.0.0', additionalBoms: ['bar-bom'])
- def additionalBom = new BillOfMaterials(groupId: 'com.example',
- artifactId: 'bar-bom', version: '1.1.0')
- def metadata = InitializrMetadataTestBuilder
- .withDefaults()
- .addBom('foo-bom', bom)
- .addBom('bar-bom', additionalBom)
- .addDependencyGroup('test', dependency)
- .build()
- request.style << 'foo'
- request.resolve(metadata)
- assertEquals(1, request.resolvedDependencies.size())
- assertEquals 2, request.boms.size()
- assertEquals bom, request.boms['foo-bom']
- assertEquals additionalBom, request.boms['bar-bom']
- }
-
- @Test
- void resolveAdditionalBomsDuplicates() {
- def request = new ProjectRequest()
- def dependency = new Dependency(id: 'foo', bom: 'foo-bom')
- def anotherDependency = new Dependency(id: 'bar', bom: 'bar-bom')
- def bom = new BillOfMaterials(groupId: 'com.example', artifactId: 'foo-bom',
- version: '1.0.0', additionalBoms: ['bar-bom'])
- def additionalBom = new BillOfMaterials(groupId: 'com.example',
- artifactId: 'bar-bom', version: '1.1.0')
- def metadata = InitializrMetadataTestBuilder
- .withDefaults()
- .addBom('foo-bom', bom)
- .addBom('bar-bom', additionalBom)
- .addDependencyGroup('test', dependency, anotherDependency)
- .build()
- request.style << 'foo' << 'bar'
- request.resolve(metadata)
- assertEquals(2, request.resolvedDependencies.size())
- assertEquals 2, request.boms.size()
- assertEquals bom, request.boms['foo-bom']
- assertEquals additionalBom, request.boms['bar-bom']
- }
-
- @Test
- void resolveAdditionalRepositories() {
- def request = new ProjectRequest()
- def dependency = new Dependency(id: 'foo', bom: 'foo-bom', repository: 'foo-repo')
- def bom = new BillOfMaterials(groupId: 'com.example', artifactId: 'foo-bom',
- version: '1.0.0', repositories: ['bar-repo'])
- def metadata = InitializrMetadataTestBuilder
- .withDefaults()
- .addBom('foo-bom', bom)
- .addRepository('foo-repo', 'foo-repo', 'http://example.com/foo', false)
- .addRepository('bar-repo', 'bar-repo', 'http://example.com/bar', false)
- .addDependencyGroup('test', dependency)
- .build()
- request.style << 'foo'
- request.resolve(metadata)
- assertEquals(1, request.resolvedDependencies.size())
- assertEquals 1, request.boms.size()
- assertEquals 2, request.repositories.size()
- assertEquals metadata.configuration.env.repositories['foo-repo'],
- request.repositories['foo-repo']
- assertEquals metadata.configuration.env.repositories['bar-repo'],
- request.repositories['bar-repo']
- }
-
- @Test
- void resolveAdditionalRepositoriesDuplicates() {
- def request = new ProjectRequest()
- def dependency = new Dependency(id: 'foo', bom: 'foo-bom', repository: 'foo-repo')
- def anotherDependency = new Dependency(id: 'bar', repository: 'bar-repo')
- def bom = new BillOfMaterials(groupId: 'com.example', artifactId: 'foo-bom',
- version: '1.0.0', repositories: ['bar-repo'])
- def metadata = InitializrMetadataTestBuilder
- .withDefaults()
- .addBom('foo-bom', bom)
- .addRepository('foo-repo', 'foo-repo', 'http://example.com/foo', false)
- .addRepository('bar-repo', 'bar-repo', 'http://example.com/bar', false)
- .addDependencyGroup('test', dependency, anotherDependency)
- .build()
- request.style << 'foo' << 'bar'
- request.resolve(metadata)
- assertEquals(2, request.resolvedDependencies.size())
- assertEquals 1, request.boms.size()
- assertEquals 2, request.repositories.size()
- assertEquals metadata.configuration.env.repositories['foo-repo'],
- request.repositories['foo-repo']
- assertEquals metadata.configuration.env.repositories['bar-repo'],
- request.repositories['bar-repo']
- }
-
- private static void assertBootStarter(Dependency actual, String name) {
- def expected = new Dependency()
- expected.asSpringBootStarter(name)
- assertDependency(actual, expected.groupId, expected.artifactId, expected.version)
- assertEquals name, actual.id
- }
-
- private static Dependency createDependency(String groupId, String artifactId, String version) {
- new Dependency(groupId: groupId, artifactId: artifactId, version: version)
- }
-
- private static void assertDependency(Dependency actual, String groupId,
- String artifactId, String version) {
- assertEquals groupId, actual.groupId
- assertEquals artifactId, actual.artifactId
- assertEquals version, actual.version
- }
-}
diff --git a/initializr-generator/src/test/groovy/io/spring/initializr/metadata/BillOfMaterialsTests.groovy b/initializr-generator/src/test/groovy/io/spring/initializr/metadata/BillOfMaterialsTests.groovy
deleted file mode 100644
index b8b025fc..00000000
--- a/initializr-generator/src/test/groovy/io/spring/initializr/metadata/BillOfMaterialsTests.groovy
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright 2012-2016 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
- *
- * http://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.metadata
-
-import io.spring.initializr.util.Version
-import io.spring.initializr.util.VersionParser
-import org.junit.Rule
-import org.junit.Test
-import org.junit.rules.ExpectedException
-
-import static org.hamcrest.CoreMatchers.equalTo
-import static org.hamcrest.CoreMatchers.nullValue
-import static org.hamcrest.CoreMatchers.sameInstance
-import static org.junit.Assert.assertThat
-
-/**
- * @author Stephane Nicoll
- */
-class BillOfMaterialsTests {
-
- @Rule
- public final ExpectedException thrown = ExpectedException.none()
-
- @Test
- void resolveSimpleBom() {
- BillOfMaterials bom = new BillOfMaterials(groupId: 'com.example',
- artifactId: 'bom', version: '1.0.0')
- bom.validate()
- BillOfMaterials resolved = bom.resolve(Version.parse('1.2.3.RELEASE'))
- assertThat(bom, sameInstance(resolved))
- }
-
- @Test
- void resolveSimpleRange() {
- BillOfMaterials bom = new BillOfMaterials(groupId: 'com.example', artifactId: 'bom',
- version: '1.0.0', versionProperty: "bom.version",
- repositories: ['repo-main'], additionalBoms: ['bom-main'])
- bom.mappings << new BillOfMaterials.Mapping(versionRange: '[1.2.0.RELEASE,1.3.0.M1)',
- version: '1.1.0')
- bom.validate()
- BillOfMaterials resolved = bom.resolve(Version.parse('1.2.3.RELEASE'))
- assertThat(resolved.groupId, equalTo('com.example'))
- assertThat(resolved.artifactId, equalTo('bom'))
- assertThat(resolved.version, equalTo('1.1.0'))
- assertThat(resolved.versionProperty, equalTo('bom.version'))
- assertThat(resolved.repositories.size(), equalTo(1))
- assertThat(resolved.repositories[0], equalTo('repo-main'))
- assertThat(resolved.additionalBoms.size(), equalTo(1))
- assertThat(resolved.additionalBoms[0], equalTo('bom-main'))
- }
-
- @Test
- void resolveRangeOverride() {
- BillOfMaterials bom = new BillOfMaterials(groupId: 'com.example',
- artifactId: 'bom', version: '1.0.0', repositories: ['repo-main'], additionalBoms: ['bom-main'])
- bom.mappings << new BillOfMaterials.Mapping(versionRange: '[1.2.0.RELEASE,1.3.0.M1)',
- version: '1.1.0', repositories: ['repo-foo'], additionalBoms: ['bom-foo'])
- bom.validate()
- BillOfMaterials resolved = bom.resolve(Version.parse('1.2.3.RELEASE'))
- assertThat(resolved.groupId, equalTo('com.example'))
- assertThat(resolved.artifactId, equalTo('bom'))
- assertThat(resolved.version, equalTo('1.1.0'))
- assertThat(resolved.versionProperty, nullValue())
- assertThat(resolved.repositories.size(), equalTo(1))
- assertThat(resolved.repositories[0], equalTo('repo-foo'))
- assertThat(resolved.additionalBoms.size(), equalTo(1))
- assertThat(resolved.additionalBoms[0], equalTo('bom-foo'))
- }
-
- @Test
- void resolveRangeOverrideAndMapping() {
- BillOfMaterials bom = new BillOfMaterials(groupId: 'com.example',
- artifactId: 'bom', version: '1.0.0', versionProperty: 'example.version')
- bom.mappings << new BillOfMaterials.Mapping(versionRange: '[1.2.0.RELEASE,1.3.0.M1)',
- version: '1.1.0')
- bom.validate()
- BillOfMaterials resolved = bom.resolve(Version.parse('1.2.3.RELEASE'))
- assertThat(resolved.groupId, equalTo('com.example'))
- assertThat(resolved.artifactId, equalTo('bom'))
- assertThat(resolved.version, equalTo('1.1.0'))
- assertThat(resolved.versionProperty, equalTo('example.version'))
- }
-
- @Test
- void noRangeAvailable() {
- BillOfMaterials bom = new BillOfMaterials(groupId: 'com.example', artifactId: 'bom')
- bom.mappings << new BillOfMaterials.Mapping(versionRange: '[1.2.0.RELEASE,1.3.0.M1)',
- version: '1.1.0')
- bom.mappings << new BillOfMaterials.Mapping(versionRange: '[1.3.0.M1,1.4.0.M1)',
- version: '1.2.0')
- bom.validate()
-
- thrown.expect(IllegalStateException)
- thrown.expectMessage('1.4.1.RELEASE')
- bom.resolve(Version.parse('1.4.1.RELEASE'))
- }
-
- @Test
- void resolveRangeWithVariablePatch() {
- BillOfMaterials bom = new BillOfMaterials(groupId: 'com.example',
- artifactId: 'bom', version: '1.0.0')
- bom.mappings << new BillOfMaterials.Mapping(
- versionRange: '[1.3.0.RELEASE,1.3.x.RELEASE]', version: '1.1.0')
- bom.mappings << new BillOfMaterials.Mapping(
- versionRange: '[1.3.x.BUILD-SNAPSHOT,1.4.0.RELEASE)', version: '1.1.1-SNAPSHOT')
- bom.validate()
-
- bom.updateVersionRange(new VersionParser(Arrays.asList(
- Version.parse("1.3.8.RELEASE"), Version.parse("1.3.9.BUILD-SNAPSHOT"))))
- assertThat(bom.resolve(Version.parse('1.3.8.RELEASE')).version, equalTo('1.1.0'))
- assertThat(bom.resolve(Version.parse('1.3.9.RELEASE')).version, equalTo('1.1.1-SNAPSHOT'))
-
- bom.updateVersionRange(new VersionParser(Arrays.asList(
- Version.parse("1.3.9.RELEASE"), Version.parse("1.3.10.BUILD-SNAPSHOT"))))
- assertThat(bom.resolve(Version.parse('1.3.8.RELEASE')).version, equalTo('1.1.0'))
- assertThat(bom.resolve(Version.parse('1.3.9.RELEASE')).version, equalTo('1.1.0'))
- }
-
-}
diff --git a/initializr-generator/src/test/groovy/io/spring/initializr/metadata/DependenciesCapabilityTests.groovy b/initializr-generator/src/test/groovy/io/spring/initializr/metadata/DependenciesCapabilityTests.groovy
deleted file mode 100644
index 79ec51f9..00000000
--- a/initializr-generator/src/test/groovy/io/spring/initializr/metadata/DependenciesCapabilityTests.groovy
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright 2012-2016 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
- *
- * http://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.metadata
-
-import org.junit.Rule
-import org.junit.Test
-import org.junit.rules.ExpectedException
-
-import static org.junit.Assert.assertEquals
-import static org.junit.Assert.assertNotNull
-import static org.junit.Assert.assertNull
-import static org.junit.Assert.assertSame
-
-/**
- * @author Stephane Nicoll
- */
-class DependenciesCapabilityTests {
-
- @Rule
- public final ExpectedException thrown = ExpectedException.none()
-
- @Test
- void indexedDependencies() {
- def dependency = new Dependency(id: 'first')
- def dependency2 = new Dependency(id: 'second')
- def capability = createDependenciesCapability('foo', dependency, dependency2)
- capability.validate()
-
- assertSame dependency, capability.get('first')
- assertSame dependency2, capability.get('second')
- assertNull capability.get('anotherId')
- }
-
- @Test
- void addTwoDependenciesWithSameId() {
- def dependency = new Dependency(id: 'conflict')
- def dependency2 = new Dependency(id: 'conflict')
- def capability = createDependenciesCapability('foo', dependency, dependency2)
-
- thrown.expect(IllegalArgumentException)
- thrown.expectMessage('conflict')
- capability.validate()
- }
-
- @Test
- void addDependencyWithAliases() {
- def dependency = new Dependency(id: 'first')
- dependency.aliases.add('alias1')
- dependency.aliases.add('alias2')
- def capability = createDependenciesCapability('foo', dependency)
- capability.validate()
-
- assertSame dependency, capability.get('first')
- assertSame dependency, capability.get('alias1')
- assertSame dependency, capability.get('alias2')
- }
-
- @Test
- void aliasClashWithAnotherDependency() {
- def dependency = new Dependency(id: 'first')
- dependency.aliases.add('alias1')
- dependency.aliases.add('alias2')
- def dependency2 = new Dependency(id: 'alias2')
-
- def capability = new DependenciesCapability()
- capability.content << createDependencyGroup('foo', dependency)
- capability.content << createDependencyGroup('bar', dependency2)
-
- thrown.expect(IllegalArgumentException)
- thrown.expectMessage('alias2')
- capability.validate()
- }
-
- @Test
- void mergeAddEntry() {
- DependenciesCapability capability = createDependenciesCapability('foo',
- new Dependency(id: 'first'), new Dependency(id: 'second'))
-
- DependenciesCapability anotherCapability = createDependenciesCapability('foo',
- new Dependency(id: 'bar'), new Dependency(id: 'biz'))
- anotherCapability.content << createDependencyGroup('bar', new Dependency(id: 'third'))
-
- capability.merge(anotherCapability)
- assertEquals 2, capability.content.size()
- assertNotNull capability.get('first')
- assertNotNull capability.get('second')
- assertNotNull capability.get('third')
- }
-
- @Test
- void addDefaultVersionRange() {
- def first = new Dependency(id: 'first')
- def second = new Dependency(id: 'second', versionRange: '1.2.3.RELEASE')
- def group = createDependencyGroup('test', first, second)
- group.versionRange = '1.2.0.RELEASE'
-
- DependenciesCapability capability = new DependenciesCapability()
- capability.content << group
- capability.validate()
-
- assertEquals '1.2.0.RELEASE', capability.get('first').versionRange
- assertEquals '1.2.3.RELEASE', capability.get('second').versionRange
- }
-
- @Test
- void addDefaultBom() {
- def first = new Dependency(id: 'first')
- def second = new Dependency(id: 'second', bom: 'da-bom')
- def group = createDependencyGroup('test', first, second)
- group.bom = 'test-bom'
-
- DependenciesCapability capability = new DependenciesCapability()
- capability.content << group
- capability.validate()
-
- assertEquals 'test-bom', capability.get('first').bom
- assertEquals 'da-bom', capability.get('second').bom
- }
-
- @Test
- void addDefaultRepository() {
- def first = new Dependency(id: 'first')
- def second = new Dependency(id: 'second', repository: 'da-repo')
- def group = createDependencyGroup('test', first, second)
- group.repository = 'test-repo'
-
- DependenciesCapability capability = new DependenciesCapability()
- capability.content << group
- capability.validate()
-
- assertEquals 'test-repo', capability.get('first').repository
- assertEquals 'da-repo', capability.get('second').repository
- }
-
-
- private static DependenciesCapability createDependenciesCapability(String groupName, Dependency... dependencies) {
- DependenciesCapability capability = new DependenciesCapability()
- DependencyGroup group = createDependencyGroup(groupName, dependencies)
- capability.content << group
- capability
- }
-
- private static DependencyGroup createDependencyGroup(String groupName, Dependency... dependencies) {
- DependencyGroup group = new DependencyGroup(name: groupName)
- for (Dependency dependency : dependencies) {
- group.content << dependency
- }
- group
- }
-
-}
diff --git a/initializr-generator/src/test/groovy/io/spring/initializr/metadata/DependencyTests.groovy b/initializr-generator/src/test/groovy/io/spring/initializr/metadata/DependencyTests.groovy
deleted file mode 100644
index ee521a11..00000000
--- a/initializr-generator/src/test/groovy/io/spring/initializr/metadata/DependencyTests.groovy
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- * Copyright 2012-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.
- * You may obtain a copy of the License at
- *
- * http://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.metadata
-
-import io.spring.initializr.util.Version
-import io.spring.initializr.util.VersionParser
-import org.junit.Rule
-import org.junit.Test
-import org.junit.rules.ExpectedException
-
-import static org.junit.Assert.assertEquals
-import static org.junit.Assert.assertNull
-import static org.junit.Assert.assertSame
-
-/**
- * @author Stephane Nicoll
- */
-class DependencyTests {
-
- @Rule
- public final ExpectedException thrown = ExpectedException.none()
-
- @Test
- void createRootSpringBootStarter() {
- Dependency d = new Dependency();
- d.asSpringBootStarter("")
- assertEquals 'org.springframework.boot', d.groupId
- assertEquals 'spring-boot-starter', d.artifactId
- }
-
- @Test
- void setCoordinatesFromId() {
- def dependency = new Dependency(id: 'org.foo:bar:1.2.3')
- dependency.resolve()
- assertEquals 'org.foo', dependency.groupId
- assertEquals 'bar', dependency.artifactId
- assertEquals '1.2.3', dependency.version
- assertEquals 'org.foo:bar:1.2.3', dependency.id
- }
-
- @Test
- void setCoordinatesFromIdNoVersion() {
- def dependency = new Dependency(id: 'org.foo:bar')
- dependency.resolve()
- assertEquals 'org.foo', dependency.groupId
- assertEquals 'bar', dependency.artifactId
- assertNull dependency.version
- assertEquals 'org.foo:bar', dependency.id
- }
-
- @Test
- void setIdFromCoordinates() {
- def dependency = new Dependency()
- dependency.groupId = 'org.foo'
- dependency.artifactId = 'bar'
- dependency.version = '1.0'
- dependency.resolve()
- assertEquals 'org.foo:bar', dependency.id
- }
-
- @Test
- void setIdFromCoordinatesNoVersion() {
- def dependency = new Dependency()
- dependency.groupId = 'org.foo'
- dependency.artifactId = 'bar'
- dependency.resolve()
- assertEquals 'org.foo:bar', dependency.id
- }
-
- @Test
- void setIdFromSimpleName() {
- def dependency = new Dependency(id: 'web')
- dependency.resolve()
- assertEquals 'org.springframework.boot', dependency.groupId
- assertEquals 'spring-boot-starter-web', dependency.artifactId
- assertNull dependency.version
- assertEquals 'web', dependency.id
- }
-
- @Test
- void invalidDependency() {
- thrown.expect(InvalidInitializrMetadataException)
- new Dependency().resolve()
- }
-
- @Test
- void invalidDependencyScope() {
- def dependency = new Dependency(id: 'web')
-
- thrown.expect(InvalidInitializrMetadataException)
- dependency.setScope('whatever')
- }
-
- @Test
- void invalidSpringBootRange() {
- def dependency = new Dependency(id: 'web')
- dependency.versionRange = 'A.B.C'
-
- thrown.expect(InvalidInitializrMetadataException)
- thrown.expectMessage('A.B.C')
- dependency.resolve()
- }
-
- @Test
- void invalidIdFormatTooManyColons() {
- def dependency = new Dependency(id: 'org.foo:bar:1.0:test:external')
-
- thrown.expect(InvalidInitializrMetadataException)
- dependency.resolve()
- }
-
- @Test
- void invalidLink() {
- def dependency = new Dependency(id : 'foo')
- dependency.links << new Link(href: 'https://example.com')
-
- thrown.expect(InvalidInitializrMetadataException)
- dependency.resolve()
- }
-
- @Test
- void generateIdWithNoGroupId() {
- def dependency = new Dependency()
- dependency.artifactId = 'bar'
- thrown.expect(IllegalArgumentException)
- dependency.generateId()
- }
-
- @Test
- void generateIdWithNoArtifactId() {
- def dependency = new Dependency()
- dependency.groupId = 'foo'
- thrown.expect(IllegalArgumentException)
- dependency.generateId()
- }
-
- @Test
- void resolveNoMapping() {
- def dependency = new Dependency(id: 'web')
- dependency.resolve()
- assertSame dependency, dependency.resolve(Version.parse('1.2.0.RELEASE'))
- }
-
- @Test
- void resolveInvalidMapping() {
- def dependency = new Dependency(id: 'web')
- dependency.mappings << new Dependency.Mapping(
- versionRange: 'foo-bar', version: '0.1.0.RELEASE')
- thrown.expect(InvalidInitializrMetadataException)
- thrown.expectMessage('foo-bar')
- dependency.resolve()
- }
-
- @Test
- void resolveVersionRequirement() {
- def dependency = new Dependency(id: 'web')
- dependency.mappings << new Dependency.Mapping(
- versionRange: '[1.1.0.RELEASE, 1.2.0.RELEASE)', version: '0.1.0.RELEASE')
- dependency.resolve()
- def resolved = dependency.resolve(Version.parse('1.1.5.RELEASE'))
- assertEquals ">=1.1.0.RELEASE and <1.2.0.RELEASE", resolved.versionRequirement
- }
-
- @Test
- void resolveMatchingVersionMapping() {
- def dependency = new Dependency(id: 'web', description: 'A web dependency', version: '0.3.0.RELEASE',
- keywords: ['foo', 'bar'], aliases: ['the-web'], facets: ['web'])
- dependency.mappings << new Dependency.Mapping(
- versionRange: '[1.1.0.RELEASE, 1.2.0.RELEASE)', version: '0.1.0.RELEASE')
- dependency.mappings << new Dependency.Mapping(
- versionRange: '[1.2.0.RELEASE, 1.3.0.RELEASE)', version: '0.2.0.RELEASE')
- dependency.resolve()
-
- validateResolvedWebDependency(dependency.resolve(Version.parse('1.1.5.RELEASE')),
- 'org.springframework.boot', 'spring-boot-starter-web', '0.1.0.RELEASE')
- validateResolvedWebDependency(dependency.resolve(Version.parse('1.2.0.RELEASE')),
- 'org.springframework.boot', 'spring-boot-starter-web', '0.2.0.RELEASE')
- validateResolvedWebDependency(dependency.resolve(Version.parse('2.1.3.M1')),
- 'org.springframework.boot', 'spring-boot-starter-web', '0.3.0.RELEASE') // default
- }
-
- @Test
- void resolveMatchArtifactMapping() {
- def dependency = new Dependency(id: 'web', description: 'A web dependency', version: '0.3.0.RELEASE',
- keywords: ['foo', 'bar'], aliases: ['the-web'], facets: ['web'])
- dependency.mappings << new Dependency.Mapping(
- versionRange: '[1.1.0.RELEASE, 1.2.0.RELEASE)', groupId: 'org.spring.boot')
- dependency.mappings << new Dependency.Mapping(
- versionRange: '[1.2.0.RELEASE, 1.3.0.RELEASE)', artifactId: 'starter-web')
- dependency.resolve()
-
- validateResolvedWebDependency(dependency.resolve(Version.parse('1.1.5.RELEASE')),
- 'org.spring.boot', 'spring-boot-starter-web', '0.3.0.RELEASE')
- validateResolvedWebDependency(dependency.resolve(Version.parse('1.2.0.RELEASE')),
- 'org.springframework.boot', 'starter-web', '0.3.0.RELEASE')
- validateResolvedWebDependency(dependency.resolve(Version.parse('2.1.3.M1')),
- 'org.springframework.boot', 'spring-boot-starter-web', '0.3.0.RELEASE') // default
- }
-
- @Test
- void resolveMatchingVersionWithVariablePatch() {
- def dependency = new Dependency(id: 'web', description: 'A web dependency', version: '0.3.0.RELEASE',
- keywords: ['foo', 'bar'], aliases: ['the-web'], facets: ['web'])
- dependency.mappings << new Dependency.Mapping(
- versionRange: '[1.1.0.RELEASE, 1.1.x.RELEASE]', version: '0.1.0.RELEASE')
- dependency.mappings << new Dependency.Mapping(
- versionRange: '[1.1.x.BUILD-SNAPSHOT, 1.2.0.RELEASE)', version: '0.2.0.RELEASE')
- dependency.resolve()
-
- dependency.updateVersionRanges(new VersionParser(Arrays.asList(
- Version.parse("1.1.5.RELEASE"), Version.parse("1.1.6.BUILD-SNAPSHOT"))))
- validateResolvedWebDependency(dependency.resolve(Version.parse('1.1.5.RELEASE')),
- 'org.springframework.boot', 'spring-boot-starter-web', '0.1.0.RELEASE')
- validateResolvedWebDependency(dependency.resolve(Version.parse('1.1.6.BUILD-SNAPSHOT')),
- 'org.springframework.boot', 'spring-boot-starter-web', '0.2.0.RELEASE')
- validateResolvedWebDependency(dependency.resolve(Version.parse('2.1.3.M1')),
- 'org.springframework.boot', 'spring-boot-starter-web', '0.3.0.RELEASE') // default
-
- dependency.updateVersionRanges(new VersionParser(Arrays.asList(
- Version.parse("1.1.6.RELEASE"), Version.parse("1.1.7.BUILD-SNAPSHOT"))))
- validateResolvedWebDependency(dependency.resolve(Version.parse('1.1.5.RELEASE')),
- 'org.springframework.boot', 'spring-boot-starter-web', '0.1.0.RELEASE')
- validateResolvedWebDependency(dependency.resolve(Version.parse('1.1.6.RELEASE')),
- 'org.springframework.boot', 'spring-boot-starter-web', '0.1.0.RELEASE')
- validateResolvedWebDependency(dependency.resolve(Version.parse('1.1.7.BUILD-SNAPSHOT')),
- 'org.springframework.boot', 'spring-boot-starter-web', '0.2.0.RELEASE')
- validateResolvedWebDependency(dependency.resolve(Version.parse('2.1.3.M1')),
- 'org.springframework.boot', 'spring-boot-starter-web', '0.3.0.RELEASE') // default
- }
-
- static void validateResolvedWebDependency(
- def dependency, def expectedGroupId, def expectedArtifactId, def expectedVersion) {
- assertEquals expectedVersion, dependency.version
- assertEquals 'web', dependency.id
- assertEquals expectedGroupId, dependency.groupId
- assertEquals expectedArtifactId, dependency.artifactId
- assertEquals 2, dependency.keywords.size()
- assertEquals 1, dependency.aliases.size()
- assertEquals 1, dependency.facets.size()
-
- }
-
-}
diff --git a/initializr-generator/src/test/groovy/io/spring/initializr/metadata/InitializrConfigurationTests.groovy b/initializr-generator/src/test/groovy/io/spring/initializr/metadata/InitializrConfigurationTests.groovy
deleted file mode 100644
index dca1d5b0..00000000
--- a/initializr-generator/src/test/groovy/io/spring/initializr/metadata/InitializrConfigurationTests.groovy
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Copyright 2012-2015 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
- *
- * http://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.metadata
-
-import org.junit.Test
-
-import static org.junit.Assert.assertEquals
-
-/**
- * @author Stephane Nicoll
- */
-class InitializrConfigurationTests {
-
- private final InitializrConfiguration properties = new InitializrConfiguration()
-
- @Test
- void generateApplicationNameSimple() {
- assertEquals 'DemoApplication', this.properties.generateApplicationName('demo')
- }
-
- @Test
- void generateApplicationNameSimpleApplication() {
- assertEquals 'DemoApplication', this.properties.generateApplicationName('demoApplication')
- }
-
- @Test
- void generateApplicationNameSimpleCamelCase() {
- assertEquals 'MyDemoApplication', this.properties.generateApplicationName('myDemo')
- }
-
- @Test
- void generateApplicationNameSimpleUnderscore() {
- assertEquals 'MyDemoApplication', this.properties.generateApplicationName('my_demo')
- }
-
- @Test
- void generateApplicationNameSimpleColon() {
- assertEquals 'MyDemoApplication', this.properties.generateApplicationName('my:demo')
- }
-
- @Test
- void generateApplicationNameSimpleSpace() {
- assertEquals 'MyDemoApplication', this.properties.generateApplicationName('my demo')
- }
-
- @Test
- void generateApplicationNamSimpleDash() {
- assertEquals 'MyDemoApplication', this.properties.generateApplicationName('my-demo')
- }
-
- @Test
- void generateApplicationNameUpperCaseUnderscore() {
- assertEquals 'MyDemoApplication', this.properties.generateApplicationName('MY_DEMO')
- }
-
- @Test
- void generateApplicationNameUpperCaseDash() {
- assertEquals 'MyDemoApplication', this.properties.generateApplicationName('MY-DEMO')
- }
-
- @Test
- void generateApplicationNameMultiSpaces() {
- assertEquals 'MyDemoApplication', this.properties.generateApplicationName(' my demo ')
- }
-
- @Test
- void generateApplicationNameMultiSpacesUpperCase() {
- assertEquals 'MyDemoApplication', this.properties.generateApplicationName(' MY DEMO ')
- }
-
- @Test
- void generateApplicationNameNull() {
- assertEquals this.properties.env.fallbackApplicationName, this.properties.generateApplicationName(null)
- }
-
- @Test
- void generateApplicationNameInvalidStartCharacter() {
- assertEquals this.properties.env.fallbackApplicationName, this.properties.generateApplicationName('1MyDemo')
- }
-
- @Test
- void generateApplicationNameInvalidPartCharacter() {
- assertEquals this.properties.env.fallbackApplicationName, this.properties.generateApplicationName('MyDe|mo')
- }
-
- @Test
- void generateApplicationNameInvalidApplicationName() {
- assertEquals this.properties.env.fallbackApplicationName, this.properties.generateApplicationName('SpringBoot')
- }
-
- @Test
- void generateApplicationNameAnotherInvalidApplicationName() {
- assertEquals this.properties.env.fallbackApplicationName, this.properties.generateApplicationName('Spring')
- }
-
- @Test
- void generatePackageNameSimple() {
- assertEquals 'com.foo', this.properties.cleanPackageName('com.foo', 'com.example')
- }
-
- @Test
- void generatePackageNameSimpleUnderscore() {
- assertEquals 'com.my_foo', this.properties.cleanPackageName('com.my_foo', 'com.example')
- }
-
- @Test
- void generatePackageNameSimpleColon() {
- assertEquals 'com.foo', this.properties.cleanPackageName('com:foo', 'com.example')
- }
-
- @Test
- void generatePackageNameMultipleDashers() {
- assertEquals 'com.foo', this.properties.cleanPackageName('com--foo', 'com.example')
- }
-
- @Test
- void generatePackageNameMultipleSpaces() {
- assertEquals 'com.foo', this.properties.cleanPackageName(' com foo ', 'com.example')
- }
-
- @Test
- void generatePackageNameNull() {
- assertEquals 'com.example', this.properties.cleanPackageName(null, 'com.example')
- }
-
- @Test
- void generatePackageNameInvalidStartCharacter() {
- assertEquals 'com.example', this.properties.cleanPackageName('0om.foo', 'com.example')
- }
-
- @Test
- void generatePackageNameInvalidPackageName() {
- assertEquals 'com.example', this.properties.cleanPackageName('org.springframework', 'com.example')
- }
-
- @Test
- void validateArtifactRepository() {
- this.properties.env.artifactRepository = 'http://foo/bar'
- assertEquals 'http://foo/bar/', this.properties.env.artifactRepository
- }
-
-}
diff --git a/initializr-generator/src/test/groovy/io/spring/initializr/metadata/InitializrMetadataBuilderTests.groovy b/initializr-generator/src/test/groovy/io/spring/initializr/metadata/InitializrMetadataBuilderTests.groovy
deleted file mode 100644
index f526bae4..00000000
--- a/initializr-generator/src/test/groovy/io/spring/initializr/metadata/InitializrMetadataBuilderTests.groovy
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * Copyright 2012-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.
- * You may obtain a copy of the License at
- *
- * http://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.metadata
-
-import org.junit.Test
-
-import org.springframework.beans.factory.config.YamlPropertiesFactoryBean
-import org.springframework.boot.bind.PropertiesConfigurationFactory
-import org.springframework.core.env.MutablePropertySources
-import org.springframework.core.env.PropertiesPropertySource
-import org.springframework.core.env.PropertySources
-import org.springframework.core.io.ClassPathResource
-import org.springframework.core.io.Resource
-
-import static org.junit.Assert.assertEquals
-import static org.junit.Assert.assertNotNull
-
-/**
- * @author Stephane Nicoll
- */
-class InitializrMetadataBuilderTests {
-
- @Test
- void loadDefaultConfig() {
- def bean = load(new ClassPathResource("application-test-default.yml"))
- def metadata = InitializrMetadataBuilder.fromInitializrProperties(bean).build()
- assertDefaultConfig(metadata)
- }
-
- @Test
- void mergeIdenticalConfig() {
- def bean = load(new ClassPathResource("application-test-default.yml"))
- def metadata = InitializrMetadataBuilder
- .fromInitializrProperties(bean)
- .withInitializrProperties(bean, true).build()
- assertDefaultConfig(metadata)
- }
-
- @Test
- void mergeConfig() {
- def config = load(new ClassPathResource("application-test-default.yml"))
- def customDefaultsConfig = load(new ClassPathResource("application-test-custom-defaults.yml"))
- def metadata = InitializrMetadataBuilder
- .fromInitializrProperties(config)
- .withInitializrProperties(customDefaultsConfig).build()
- assertDefaultConfig(metadata)
- assertEquals 'org.foo', metadata.groupId.content
- assertEquals 'foo-bar', metadata.artifactId.content
- assertEquals '1.2.4-SNAPSHOT', metadata.version.content
- assertEquals 'FooBar', metadata.name.content
- assertEquals 'FooBar Project', metadata.description.content
- assertEquals 'org.foo.demo', metadata.packageName.content
- }
-
- @Test
- void mergeMetadata() {
- def metadata = InitializrMetadataBuilder.create().withInitializrMetadata(
- new ClassPathResource('metadata/config/test-min.json')).build()
- assertEquals false, metadata.configuration.env.forceSsl
- assertEquals 1, metadata.dependencies.content.size()
- Dependency dependency = metadata.dependencies.get('test')
- assertNotNull dependency
- assertEquals 'org.springframework.boot', dependency.groupId
- assertEquals 1, metadata.types.content.size()
- assertEquals 2, metadata.bootVersions.content.size()
- assertEquals 2, metadata.packagings.content.size()
- assertEquals 1, metadata.javaVersions.content.size()
- assertEquals 3, metadata.languages.content.size()
- assertEquals 'metadata-merge', metadata.name.content
- assertEquals 'Demo project for metadata merge', metadata.description.content
- assertEquals 'org.acme', metadata.groupId.content
- assertEquals 'metadata', metadata.artifactId.content
- assertEquals '1.0.0-SNAPSHOT', metadata.version.content
- assertEquals 'org.acme.demo', metadata.packageName.content
- }
-
- @Test
- void mergeMetadataWithBom() {
- def metadata = InitializrMetadataBuilder.create().withInitializrMetadata(
- new ClassPathResource('metadata/config/test-bom.json')).build()
-
- def boms = metadata.configuration.env.boms
- assertEquals 2, boms.size()
- BillOfMaterials myBom = boms['my-bom']
- assertNotNull myBom
- assertEquals 'org.acme', myBom.groupId
- assertEquals 'my-bom', myBom.artifactId
- assertEquals '1.2.3.RELEASE', myBom.version
-
- BillOfMaterials anotherBom = boms['another-bom']
- assertNotNull anotherBom
- assertEquals 'org.acme', anotherBom.groupId
- assertEquals 'another-bom', anotherBom.artifactId
- assertEquals '4.5.6.RELEASE', anotherBom.version
- }
-
- @Test
- void mergeMetadataWithRepository() {
- def metadata = InitializrMetadataBuilder.create().withInitializrMetadata(
- new ClassPathResource('metadata/config/test-repository.json')).build()
-
- def repositories = metadata.configuration.env.repositories
- assertEquals 4, repositories.size() // 2 standard repos
- Repository myRepo = repositories['my-repo']
- assertNotNull myRepo
- assertEquals 'my repo', myRepo.name
- assertEquals new URL('http://example.com/my'), myRepo.url
- assertEquals true, myRepo.snapshotsEnabled
-
- Repository anotherRepo = repositories['another-repo']
- assertNotNull anotherRepo
- assertEquals 'another repo', anotherRepo.name
- assertEquals new URL('http://example.com/another'), anotherRepo.url
- assertEquals false, anotherRepo.snapshotsEnabled
- }
-
- @Test
- void mergeConfigurationDisabledByDefault() {
- def config = load(new ClassPathResource("application-test-default.yml"))
- def customDefaultsConfig = load(new ClassPathResource("application-test-custom-env.yml"))
- def metadata = InitializrMetadataBuilder
- .fromInitializrProperties(config)
- .withInitializrProperties(customDefaultsConfig).build()
- InitializrConfiguration.Env defaultEnv = new InitializrConfiguration().env
- InitializrConfiguration.Env actualEnv = metadata.configuration.env
- assertEquals defaultEnv.artifactRepository, actualEnv.artifactRepository
- assertEquals defaultEnv.springBootMetadataUrl, actualEnv.springBootMetadataUrl
- assertEquals defaultEnv.fallbackApplicationName, actualEnv.fallbackApplicationName
- assertEquals defaultEnv.forceSsl, actualEnv.forceSsl
- assertEquals defaultEnv.kotlin.version, actualEnv.kotlin.version
- }
-
- @Test
- void mergeConfiguration() {
- def config = load(new ClassPathResource("application-test-default.yml"))
- def customDefaultsConfig = load(new ClassPathResource("application-test-custom-env.yml"))
- def metadata = InitializrMetadataBuilder
- .fromInitializrProperties(config)
- .withInitializrProperties(customDefaultsConfig, true).build()
- InitializrConfiguration.Env defaultEnv = new InitializrConfiguration().env
- InitializrConfiguration.Env actualEnv = metadata.configuration.env
- assertEquals 'https://repo.spring.io/lib-release/', actualEnv.artifactRepository
- assertEquals defaultEnv.springBootMetadataUrl, actualEnv.springBootMetadataUrl
- assertEquals 'FooBarApplication', actualEnv.fallbackApplicationName
- assertEquals false, actualEnv.forceSsl
- assertEquals '1.0.0-beta-2423', actualEnv.kotlin.version
- }
-
- @Test
- void addDependencyInCustomizer() {
- def group = new DependencyGroup(name: 'Extra')
- def dependency = new Dependency(id: 'com.foo:foo:1.0.0')
- group.content << dependency
- def metadata = InitializrMetadataBuilder.create().withCustomizer(new InitializrMetadataCustomizer() {
- @Override
- void customize(InitializrMetadata metadata) {
- metadata.dependencies.content << group
- }
- }).build()
- assertEquals 1, metadata.dependencies.content.size()
- assertEquals group, metadata.dependencies.content[0]
- }
-
- private static assertDefaultConfig(InitializrMetadata metadata) {
- assertNotNull metadata
- assertEquals "Wrong number of dependencies", 9, metadata.dependencies.all.size()
- assertEquals "Wrong number of dependency group", 2, metadata.dependencies.content.size()
- assertEquals "Wrong number of types", 4, metadata.types.content.size()
- }
-
- private static InitializrProperties load(Resource resource) {
- PropertiesConfigurationFactory factory =
- new PropertiesConfigurationFactory<>(InitializrProperties)
- factory.setTargetName("initializr")
- PropertySources sources = new MutablePropertySources()
- sources.addFirst(new PropertiesPropertySource("main", loadProperties(resource)))
- factory.setPropertySources(sources)
- factory.afterPropertiesSet();
- return factory.getObject();
- }
-
- private static Properties loadProperties(Resource resource) {
- YamlPropertiesFactoryBean yamlFactory = new YamlPropertiesFactoryBean()
- yamlFactory.setResources(resource)
- yamlFactory.afterPropertiesSet()
- return yamlFactory.getObject()
- }
-
-}
diff --git a/initializr-generator/src/test/groovy/io/spring/initializr/metadata/InitializrMetadataTests.groovy b/initializr-generator/src/test/groovy/io/spring/initializr/metadata/InitializrMetadataTests.groovy
deleted file mode 100644
index ed585bf7..00000000
--- a/initializr-generator/src/test/groovy/io/spring/initializr/metadata/InitializrMetadataTests.groovy
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * Copyright 2012-2016 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
- *
- * http://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.metadata
-
-import io.spring.initializr.test.metadata.InitializrMetadataTestBuilder
-import io.spring.initializr.util.Version
-import org.junit.Rule
-import org.junit.Test
-import org.junit.rules.ExpectedException
-
-import static org.assertj.core.api.Assertions.assertThat
-
-/**
- * @author Stephane Nicoll
- */
-class InitializrMetadataTests {
-
- @Rule
- public final ExpectedException thrown = ExpectedException.none()
-
- @Test
- void invalidBom() {
- def foo = new Dependency(id: 'foo', groupId: 'org.acme', artifactId: 'foo', bom: 'foo-bom')
- InitializrMetadataTestBuilder builder = InitializrMetadataTestBuilder
- .withDefaults().addBom('my-bom', 'org.acme', 'foo', '1.2.3')
- .addDependencyGroup('test', foo);
-
- thrown.expect(InvalidInitializrMetadataException)
- thrown.expectMessage("foo-bom")
- thrown.expectMessage("my-bom")
- builder.build()
- }
-
- @Test
- void invalidRepository() {
- def foo = new Dependency(id: 'foo', groupId: 'org.acme', artifactId: 'foo', repository: 'foo-repo')
- InitializrMetadataTestBuilder builder = InitializrMetadataTestBuilder
- .withDefaults().addRepository('my-repo', 'repo', 'http://example.com/repo', true)
- .addDependencyGroup('test', foo);
-
- thrown.expect(InvalidInitializrMetadataException)
- thrown.expectMessage("foo-repo")
- thrown.expectMessage("my-repo")
- builder.build()
- }
-
- @Test
- void invalidBomNoVersion() {
- def bom = new BillOfMaterials(groupId: 'org.acme', artifactId: 'foo-bom')
-
- InitializrMetadataTestBuilder builder = InitializrMetadataTestBuilder
- .withDefaults().addBom('foo-bom', bom)
-
- thrown.expect(InvalidInitializrMetadataException)
- thrown.expectMessage("No version")
- thrown.expectMessage("foo-bom")
- builder.build()
- }
-
- @Test
- void invalidBomUnknownRepository() {
- def bom = new BillOfMaterials(groupId: 'org.acme', artifactId: 'foo-bom',
- version: '1.0.0.RELEASE', repositories: ['foo-repo'])
-
- InitializrMetadataTestBuilder builder = InitializrMetadataTestBuilder
- .withDefaults().addBom('foo-bom', bom)
-
- thrown.expect(InvalidInitializrMetadataException)
- thrown.expectMessage("invalid repository id foo-repo")
- thrown.expectMessage("foo-bom")
- builder.build()
- }
-
- @Test
- void invalidBomUnknownAdditionalBom() {
- def bom = new BillOfMaterials(groupId: 'org.acme', artifactId: 'foo-bom',
- version: '1.0.0.RELEASE', additionalBoms: ['bar-bom', 'biz-bom'])
- def barBom = new BillOfMaterials(groupId: 'org.acme', artifactId: 'bar-bom',
- version: '1.0.0.RELEASE')
-
- InitializrMetadataTestBuilder builder = InitializrMetadataTestBuilder
- .withDefaults().addBom('foo-bom', bom).addBom('bar-bom', barBom)
-
- thrown.expect(InvalidInitializrMetadataException)
- thrown.expectMessage("invalid additional bom")
- thrown.expectMessage("biz-bom")
- builder.build()
- }
-
- @Test
- void invalidBomVersionRangeMapping() {
- def bom = new BillOfMaterials(groupId: 'org.acme', artifactId: 'foo-bom')
- bom.mappings << new BillOfMaterials.Mapping(versionRange: '[1.2.0.RELEASE,1.3.0.M1)', version: '1.0.0')
- bom.mappings << new BillOfMaterials.Mapping(versionRange: 'FOO_BAR', version: '1.2.0')
-
- InitializrMetadataTestBuilder builder = InitializrMetadataTestBuilder
- .withDefaults().addBom('foo-bom', bom)
-
- thrown.expect(InvalidInitializrMetadataException)
- thrown.expectMessage("FOO_BAR")
- thrown.expectMessage("foo-bom")
- builder.build()
- }
-
- @Test
- void invalidBomVersionRangeMappingUnknownRepo() {
- def bom = new BillOfMaterials(groupId: 'org.acme', artifactId: 'foo-bom')
- bom.mappings << new BillOfMaterials.Mapping(versionRange: '[1.0.0.RELEASE,1.3.0.M1)', version: '1.0.0')
- bom.mappings << new BillOfMaterials.Mapping(versionRange: '1.3.0.M2', version: '1.2.0', repositories: ['foo-repo'])
-
- InitializrMetadataTestBuilder builder = InitializrMetadataTestBuilder
- .withDefaults().addBom('foo-bom', bom)
-
- thrown.expect(InvalidInitializrMetadataException)
- thrown.expectMessage("invalid repository id foo-repo")
- thrown.expectMessage('1.3.0.M2')
- thrown.expectMessage("foo-bom")
- builder.build()
- }
-
- @Test
- void invalidBomVersionRangeMappingUnknownAdditionalBom() {
- def bom = new BillOfMaterials(groupId: 'org.acme', artifactId: 'foo-bom')
- bom.mappings << new BillOfMaterials.Mapping(versionRange: '[1.0.0.RELEASE,1.3.0.M1)', version: '1.0.0')
- bom.mappings << new BillOfMaterials.Mapping(versionRange: '1.3.0.M2', version: '1.2.0',
- additionalBoms: ['bar-bom'])
-
- InitializrMetadataTestBuilder builder = InitializrMetadataTestBuilder
- .withDefaults().addBom('foo-bom', bom)
-
- thrown.expect(InvalidInitializrMetadataException)
- thrown.expectMessage("invalid additional bom")
- thrown.expectMessage('1.3.0.M2')
- thrown.expectMessage("bar-bom")
- builder.build()
- }
-
- @Test
- void updateSpringBootVersions() {
- def bom = new BillOfMaterials(groupId: 'org.acme', artifactId: 'foo-bom')
- bom.mappings << new BillOfMaterials.Mapping(versionRange: '[1.3.0.RELEASE,1.3.x.RELEASE]', version: '1.0.0')
- bom.mappings << new BillOfMaterials.Mapping(versionRange: '1.3.x.BUILD-SNAPSHOT', version: '1.1.0-BUILD-SNAPSHOT')
- def dependency = new Dependency(id: 'bar')
- dependency.mappings << new Dependency.Mapping(
- versionRange: '[1.3.0.RELEASE, 1.3.x.RELEASE]', version: '0.1.0.RELEASE')
- dependency.mappings << new Dependency.Mapping(
- versionRange: '1.3.x.BUILD-SNAPSHOT', version: '0.2.0.RELEASE')
- InitializrMetadata metadata = InitializrMetadataTestBuilder
- .withDefaults().addDependencyGroup("test", dependency)
- .addBom('foo-bom', bom).build();
-
- List bootVersions = Arrays.asList(
- new DefaultMetadataElement(id: '1.3.6.RELEASE', name: '1.3.6'),
- new DefaultMetadataElement(id: '1.3.7.BUILD-SNAPSHOT', name: '1.3.7'))
- metadata.updateSpringBootVersions(bootVersions)
- assertThat(metadata.configuration.env.boms['foo-bom']
- .resolve(Version.parse('1.3.6.RELEASE')).version).isEqualTo('1.0.0')
- assertThat(metadata.configuration.env.boms['foo-bom']
- .resolve(Version.parse('1.3.7.BUILD-SNAPSHOT')).version).isEqualTo('1.1.0-BUILD-SNAPSHOT')
- assertThat(metadata.dependencies.get('bar')
- .resolve(Version.parse('1.3.6.RELEASE')).version).isEqualTo('0.1.0.RELEASE')
- assertThat(metadata.dependencies.get('bar')
- .resolve(Version.parse('1.3.7.BUILD-SNAPSHOT')).version).isEqualTo('0.2.0.RELEASE')
- }
-
- @Test
- void invalidParentMissingVersion() {
- InitializrMetadataTestBuilder builder = InitializrMetadataTestBuilder
- .withDefaults()
- .setMavenParent('org.foo', 'foo-parent', null, false)
-
- thrown.expect(InvalidInitializrMetadataException)
- thrown.expectMessage("Custom maven pom requires groupId, artifactId and version")
- builder.build()
- }
-
-}
diff --git a/initializr-generator/src/test/groovy/io/spring/initializr/metadata/LinkTests.groovy b/initializr-generator/src/test/groovy/io/spring/initializr/metadata/LinkTests.groovy
deleted file mode 100644
index 58afbfe2..00000000
--- a/initializr-generator/src/test/groovy/io/spring/initializr/metadata/LinkTests.groovy
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright 2012-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.
- * You may obtain a copy of the License at
- *
- * http://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.metadata
-
-import org.junit.Rule
-import org.junit.Test
-import org.junit.rules.ExpectedException
-
-/**
- * Tests for {@link Link}.
- *
- * @author Stephane Nicoll
- */
-class LinkTests {
-
- @Rule
- public final ExpectedException thrown = ExpectedException.none()
-
- @Test
- void resolveInvalidLinkNoRel() {
- def link = new Link(href: 'https://example.com')
- thrown.expect(InvalidInitializrMetadataException)
- link.resolve()
- }
-
- @Test
- void resolveInvalidLinkNoHref() {
- def link = new Link(rel: 'reference', description: 'foo doc')
-
- thrown.expect(InvalidInitializrMetadataException)
- link.resolve()
- }
-
- @Test
- void resolveLinkNoVariables() {
- def link = new Link(rel: 'reference', href: 'https://example.com/2')
- link.resolve()
- assert !link.templated
- assert link.templateVariables.size() == 0
- }
-
- @Test
- void resolveLinkWithVariables() {
- def link = new Link(rel: 'reference', href: 'https://example.com/{a}/2/{b}')
- link.resolve()
- assert link.templated
- assert link.templateVariables.size() == 2
- assert link.templateVariables.contains('a')
- assert link.templateVariables.contains('b')
- }
-
- @Test
- void expandLink() {
- def link = new Link(rel: 'reference', href: 'https://example.com/{a}/2/{b}')
- link.resolve()
- assert link.expand(['a': 'test', 'b': 'another']) ==
- new URI('https://example.com/test/2/another')
- }
-
- @Test
- void expandLinkWithSameAttributeAtTwoPlaces() {
- def link = new Link(rel: 'reference', href: 'https://example.com/{a}/2/{a}')
- link.resolve()
- assert link.expand(['a': 'test', 'b': 'another']) ==
- new URI('https://example.com/test/2/test')
- }
-
- @Test
- void expandLinkMissingVariable() {
- def link = new Link(rel: 'reference', href: 'https://example.com/{a}/2/{b}')
- link.resolve()
-
- thrown.expect(IllegalArgumentException)
- thrown.expectMessage("missing value for 'b'")
- link.expand(['a': 'test'])
- }
-
-}
diff --git a/initializr-generator/src/test/groovy/io/spring/initializr/metadata/SingleSelectCapabilityTests.groovy b/initializr-generator/src/test/groovy/io/spring/initializr/metadata/SingleSelectCapabilityTests.groovy
deleted file mode 100644
index 13d91d5b..00000000
--- a/initializr-generator/src/test/groovy/io/spring/initializr/metadata/SingleSelectCapabilityTests.groovy
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright 2012-2015 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
- *
- * http://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.metadata
-
-import org.junit.Test
-
-import static org.junit.Assert.assertEquals
-import static org.junit.Assert.assertNull
-
-/**
- * @author Stephane Nicoll
- */
-class SingleSelectCapabilityTests {
-
- @Test
- void defaultEmpty() {
- SingleSelectCapability capability = new SingleSelectCapability('test')
- assertNull capability.default
- }
-
- @Test
- void defaultNoDefault() {
- SingleSelectCapability capability = new SingleSelectCapability('test')
- capability.content << new DefaultMetadataElement(id: 'foo', default: false)
- capability.content << new DefaultMetadataElement(id: 'bar', default: false)
- assertNull capability.default
- }
-
- @Test
- void defaultType() {
- SingleSelectCapability capability = new SingleSelectCapability('test')
- DefaultMetadataElement first = new DefaultMetadataElement(id: 'foo', default: false)
- DefaultMetadataElement second = new DefaultMetadataElement(id: 'bar', default: true)
- capability.content << first << second
- assertEquals second, capability.default
- }
-
- @Test
- void mergeAddEntry() {
- SingleSelectCapability capability = new SingleSelectCapability('test')
- def foo = new DefaultMetadataElement(id: 'foo', default: false)
- capability.content << foo
-
- SingleSelectCapability anotherCapability = new SingleSelectCapability('test')
- def bar = new DefaultMetadataElement(id: 'bar', default: false)
- anotherCapability.content << bar
-
- capability.merge(anotherCapability)
- assertEquals 2, capability.content.size()
- assertEquals foo, capability.get('foo')
- assertEquals bar, capability.get('bar')
- }
-
-}
diff --git a/initializr-generator/src/test/groovy/io/spring/initializr/metadata/TextCapabilityTests.groovy b/initializr-generator/src/test/groovy/io/spring/initializr/metadata/TextCapabilityTests.groovy
deleted file mode 100644
index b37b8b3d..00000000
--- a/initializr-generator/src/test/groovy/io/spring/initializr/metadata/TextCapabilityTests.groovy
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright 2012-2015 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
- *
- * http://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.metadata
-
-import org.junit.Test
-
-import static org.junit.Assert.assertEquals
-
-/**
- * @author Stephane Nicoll
- */
-class TextCapabilityTests {
-
- @Test
- void mergeValue() {
- TextCapability capability = new TextCapability('foo')
- capability.content = '1234'
- def another = new TextCapability('foo')
- another.content = '4567'
- capability.merge(another)
- assertEquals 'foo', capability.id
- assertEquals ServiceCapabilityType.TEXT, capability.type
- assertEquals '4567', capability.content
- }
-
- @Test
- void mergeTitle() {
- TextCapability capability = new TextCapability('foo', 'Foo', 'my desc')
- capability.merge(new TextCapability('foo', 'AnotherFoo', ''))
- assertEquals 'foo', capability.id
- assertEquals ServiceCapabilityType.TEXT, capability.type
- assertEquals 'AnotherFoo', capability.title
- assertEquals 'my desc', capability.description
- }
-
- @Test
- void mergeDescription() {
- TextCapability capability = new TextCapability('foo', 'Foo', 'my desc')
- capability.merge(new TextCapability('foo', '', 'another desc'))
- assertEquals 'foo', capability.id
- assertEquals ServiceCapabilityType.TEXT, capability.type
- assertEquals 'Foo', capability.title
- assertEquals 'another desc', capability.description
- }
-
-}
diff --git a/initializr-generator/src/test/groovy/io/spring/initializr/metadata/TypeCapabilityTests.groovy b/initializr-generator/src/test/groovy/io/spring/initializr/metadata/TypeCapabilityTests.groovy
deleted file mode 100644
index 26b57758..00000000
--- a/initializr-generator/src/test/groovy/io/spring/initializr/metadata/TypeCapabilityTests.groovy
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright 2012-2015 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
- *
- * http://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.metadata
-
-import org.junit.Test
-
-import static org.junit.Assert.assertEquals
-import static org.junit.Assert.assertNull
-
-/**
- * @author Stephane Nicoll
- */
-class TypeCapabilityTests {
-
- @Test
- void defaultEmpty() {
- TypeCapability capability = new TypeCapability()
- assertNull capability.default
- }
-
- @Test
- void defaultNoDefault() {
- TypeCapability capability = new TypeCapability()
- capability.content << new Type(id: 'foo', default: false) << new Type(id: 'bar', default: false)
- assertNull capability.default
- }
-
- @Test
- void defaultType() {
- TypeCapability capability = new TypeCapability()
- Type first = new Type(id: 'foo', default: false)
- Type second = new Type(id: 'bar', default: true)
- capability.content << first << second
- assertEquals second, capability.default
- }
-
- @Test
- void mergeAddEntry() {
- TypeCapability capability = new TypeCapability()
- def foo = new Type(id: 'foo', default: false)
- capability.content << foo
-
- TypeCapability anotherCapability = new TypeCapability()
- def foo2 =new Type(id: 'foo', default: true)
- def bar =new Type(id: 'bar', default: true)
- anotherCapability.content << foo2 << bar
-
- capability.merge(anotherCapability)
- assertEquals 2, capability.content.size()
- assertEquals foo, capability.get('foo')
- assertEquals bar, capability.get('bar')
- assertEquals bar, capability.default
- }
-
-}
diff --git a/initializr-generator/src/test/groovy/io/spring/initializr/test/generator/GradleBuildAssert.groovy b/initializr-generator/src/test/groovy/io/spring/initializr/test/generator/GradleBuildAssert.groovy
deleted file mode 100644
index d190f9c0..00000000
--- a/initializr-generator/src/test/groovy/io/spring/initializr/test/generator/GradleBuildAssert.groovy
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright 2012-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.
- * You may obtain a copy of the License at
- *
- * http://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.test.generator
-
-import io.spring.initializr.generator.ProjectRequest
-
-import static org.junit.Assert.assertFalse
-import static org.junit.Assert.assertTrue
-
-/**
- * Very simple assertions for the gradle build.
- *
- * @author Stephane Nicoll
- */
-class GradleBuildAssert {
-
- private final String content
-
- GradleBuildAssert(String content) {
- this.content = content
- }
-
- /**
- * Validate that this generated gradle build validates against its request.
- */
- GradleBuildAssert validateProjectRequest(ProjectRequest request) {
- hasArtifactId(request.artifactId).hasVersion(request.version).
- hasBootVersion(request.bootVersion).hasJavaVersion(request.javaVersion)
- }
-
- GradleBuildAssert hasArtifactId(String artifactId) {
- contains("baseName = '$artifactId'")
- }
-
- GradleBuildAssert hasVersion(String version) {
- contains("version = '$version'")
- }
-
- GradleBuildAssert hasBootVersion(String bootVersion) {
- contains("springBootVersion = '$bootVersion'")
- }
-
- GradleBuildAssert hasJavaVersion(String javaVersion) {
- contains("sourceCompatibility = $javaVersion")
- }
-
- GradleBuildAssert hasSnapshotRepository() {
- contains('https://repo.spring.io/snapshot')
- }
-
- GradleBuildAssert hasRepository(String url) {
- contains("maven { url \"$url\" }")
- }
-
- GradleBuildAssert contains(String expression) {
- assertTrue "$expression has not been found in gradle build $content", content.contains(expression)
- this
- }
-
- GradleBuildAssert doesNotContain(String expression) {
- assertFalse "$expression is not expected in gradle build $content", content.contains(expression)
- this
- }
-}
diff --git a/initializr-generator/src/test/groovy/io/spring/initializr/test/generator/PomAssert.groovy b/initializr-generator/src/test/groovy/io/spring/initializr/test/generator/PomAssert.groovy
deleted file mode 100644
index 0fbe7e41..00000000
--- a/initializr-generator/src/test/groovy/io/spring/initializr/test/generator/PomAssert.groovy
+++ /dev/null
@@ -1,376 +0,0 @@
-/*
- * Copyright 2012-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.
- * You may obtain a copy of the License at
- *
- * http://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.test.generator
-
-import io.spring.initializr.generator.ProjectRequest
-import io.spring.initializr.metadata.BillOfMaterials
-import io.spring.initializr.metadata.Dependency
-import io.spring.initializr.metadata.InitializrConfiguration.Env.Maven.ParentPom
-import io.spring.initializr.metadata.Repository
-import org.custommonkey.xmlunit.SimpleNamespaceContext
-import org.custommonkey.xmlunit.XMLUnit
-import org.custommonkey.xmlunit.XpathEngine
-import org.junit.Assert
-import org.w3c.dom.Document
-import org.w3c.dom.Element
-
-import static org.junit.Assert.assertEquals
-import static org.junit.Assert.assertFalse
-import static org.junit.Assert.assertNotNull
-import static org.junit.Assert.assertTrue
-
-/**
- * XPath assertions that are specific to a standard Maven POM.
- *
- * @author Stephane Nicoll
- */
-class PomAssert {
-
- final XpathEngine eng
- final Document doc
- final ParentPom parentPom
- final Map