diff --git a/initializr/src/main/groovy/io/spring/initializr/generator/ProjectRequest.groovy b/initializr/src/main/groovy/io/spring/initializr/generator/ProjectRequest.groovy
index 11c6c7b7..93251d4f 100644
--- a/initializr/src/main/groovy/io/spring/initializr/generator/ProjectRequest.groovy
+++ b/initializr/src/main/groovy/io/spring/initializr/generator/ProjectRequest.groovy
@@ -17,6 +17,7 @@
package io.spring.initializr.generator
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.Type
@@ -59,6 +60,8 @@ class ProjectRequest {
// Resolved dependencies based on the ids provided by either "style" or "dependencies"
List resolvedDependencies
+ final List boms = []
+
def facets = []
def build
@@ -92,6 +95,7 @@ class ProjectRequest {
}
String actualBootVersion = bootVersion ?: metadata.bootVersions.default.id
Version requestedVersion = Version.parse(actualBootVersion)
+ Set bomIds = []
resolvedDependencies.each {
it.facets.each {
if (!facets.contains(it)) {
@@ -105,6 +109,13 @@ class ProjectRequest {
"with Spring Boot $bootVersion")
}
}
+ if (it.bom) {
+ String bomId = it.bom
+ if (!bomIds.contains(bomId)) {
+ bomIds << bomId
+ boms << metadata.configuration.env.boms[bomId]
+ }
+ }
}
if (this.type) {
diff --git a/initializr/src/main/groovy/io/spring/initializr/metadata/BillOfMaterials.groovy b/initializr/src/main/groovy/io/spring/initializr/metadata/BillOfMaterials.groovy
new file mode 100644
index 00000000..bf8766a4
--- /dev/null
+++ b/initializr/src/main/groovy/io/spring/initializr/metadata/BillOfMaterials.groovy
@@ -0,0 +1,35 @@
+/*
+ * 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 groovy.transform.ToString
+
+/**
+ * Define a Bill Of Materials to be represented in the generated project
+ * if a dependency refers to it.
+ *
+ * @author Stephane Nicoll
+ * @since 1.0
+ */
+@ToString(ignoreNulls = true, includePackage = false)
+class BillOfMaterials {
+
+ String groupId
+ String artifactId
+ String version
+
+}
diff --git a/initializr/src/main/groovy/io/spring/initializr/metadata/Dependency.groovy b/initializr/src/main/groovy/io/spring/initializr/metadata/Dependency.groovy
index 2c6118e5..b45462b4 100644
--- a/initializr/src/main/groovy/io/spring/initializr/metadata/Dependency.groovy
+++ b/initializr/src/main/groovy/io/spring/initializr/metadata/Dependency.groovy
@@ -16,6 +16,7 @@
package io.spring.initializr.metadata
+import com.fasterxml.jackson.annotation.JsonInclude
import groovy.transform.ToString
import io.spring.initializr.util.InvalidVersionException
import io.spring.initializr.util.VersionRange
@@ -28,6 +29,7 @@ import io.spring.initializr.util.VersionRange
* @since 1.0
*/
@ToString(ignoreNulls = true, includePackage = false)
+@JsonInclude(JsonInclude.Include.NON_NULL)
class Dependency extends MetadataElement {
static final String SCOPE_COMPILE = 'compile'
@@ -57,6 +59,8 @@ class Dependency extends MetadataElement {
String versionRange
+ String bom
+
void setScope(String scope) {
if (!SCOPE_ALL.contains(scope)) {
throw new InvalidInitializrMetadataException("Invalid scope $scope must be one of $SCOPE_ALL")
diff --git a/initializr/src/main/groovy/io/spring/initializr/InitializrConfiguration.groovy b/initializr/src/main/groovy/io/spring/initializr/metadata/InitializrConfiguration.groovy
similarity index 93%
rename from initializr/src/main/groovy/io/spring/initializr/InitializrConfiguration.groovy
rename to initializr/src/main/groovy/io/spring/initializr/metadata/InitializrConfiguration.groovy
index 3174bce2..94300fa0 100644
--- a/initializr/src/main/groovy/io/spring/initializr/InitializrConfiguration.groovy
+++ b/initializr/src/main/groovy/io/spring/initializr/metadata/InitializrConfiguration.groovy
@@ -14,8 +14,7 @@
* limitations under the License.
*/
-package io.spring.initializr
-
+package io.spring.initializr.metadata
/**
* Various configuration options used by the service.
*
@@ -113,6 +112,11 @@ class InitializrConfiguration {
*/
boolean forceSsl = true
+ /**
+ * The {@link BillOfMaterials} that are referenced in this instance.
+ */
+ final Map boms = [:]
+
void setArtifactRepository(String artifactRepository) {
if (!artifactRepository.endsWith('/')) {
artifactRepository = artifactRepository + '/'
@@ -126,7 +130,13 @@ class InitializrConfiguration {
fallbackApplicationName = other.fallbackApplicationName
invalidApplicationNames = other.invalidApplicationNames
forceSsl = other.forceSsl
+ other.boms.each { id, bom ->
+ if (!boms[id]) {
+ boms[id] = bom
+ }
+ }
}
}
+
}
diff --git a/initializr/src/main/groovy/io/spring/initializr/metadata/InitializrMetadata.groovy b/initializr/src/main/groovy/io/spring/initializr/metadata/InitializrMetadata.groovy
index f34cc042..5b31a28c 100644
--- a/initializr/src/main/groovy/io/spring/initializr/metadata/InitializrMetadata.groovy
+++ b/initializr/src/main/groovy/io/spring/initializr/metadata/InitializrMetadata.groovy
@@ -15,9 +15,6 @@
*/
package io.spring.initializr.metadata
-
-import io.spring.initializr.InitializrConfiguration
-
/**
* Meta-data used to generate a project.
*
@@ -86,6 +83,14 @@ class InitializrMetadata {
*/
void validate() {
dependencies.validate()
+
+ for (Dependency dependency : dependencies.all) {
+ def boms = configuration.env.boms
+ if (dependency.bom && !boms[dependency.bom]) {
+ throw new InvalidInitializrMetadataException("Dependency $dependency " +
+ "defines an invalid BOM id $dependency.bom, available boms $boms")
+ }
+ }
}
/**
@@ -147,7 +152,7 @@ class InitializrMetadata {
@Override
String getContent() {
String value = super.getContent()
- value == null ? nameCapability.content.replace('-', '.') : value
+ value ?: (nameCapability.content != null ? nameCapability.content.replace('-', '.') : null)
}
}
diff --git a/initializr/src/main/groovy/io/spring/initializr/metadata/InitializrMetadataBuilder.groovy b/initializr/src/main/groovy/io/spring/initializr/metadata/InitializrMetadataBuilder.groovy
index a747c6f8..47c23653 100644
--- a/initializr/src/main/groovy/io/spring/initializr/metadata/InitializrMetadataBuilder.groovy
+++ b/initializr/src/main/groovy/io/spring/initializr/metadata/InitializrMetadataBuilder.groovy
@@ -20,7 +20,6 @@ import java.nio.charset.Charset
import com.fasterxml.jackson.databind.ObjectMapper
import groovy.util.logging.Log
-import io.spring.initializr.InitializrConfiguration
import org.springframework.core.io.Resource
import org.springframework.util.StreamUtils
diff --git a/initializr/src/main/groovy/io/spring/initializr/metadata/InitializrProperties.groovy b/initializr/src/main/groovy/io/spring/initializr/metadata/InitializrProperties.groovy
index 5502ae56..35dd86a0 100644
--- a/initializr/src/main/groovy/io/spring/initializr/metadata/InitializrProperties.groovy
+++ b/initializr/src/main/groovy/io/spring/initializr/metadata/InitializrProperties.groovy
@@ -17,7 +17,6 @@
package io.spring.initializr.metadata
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
-import io.spring.initializr.InitializrConfiguration
import org.springframework.boot.context.properties.ConfigurationProperties
diff --git a/initializr/src/main/groovy/io/spring/initializr/metadata/ServiceCapability.groovy b/initializr/src/main/groovy/io/spring/initializr/metadata/ServiceCapability.groovy
index 031b2c19..2ebbf7b7 100644
--- a/initializr/src/main/groovy/io/spring/initializr/metadata/ServiceCapability.groovy
+++ b/initializr/src/main/groovy/io/spring/initializr/metadata/ServiceCapability.groovy
@@ -17,6 +17,7 @@
package io.spring.initializr.metadata
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
+import com.fasterxml.jackson.annotation.JsonInclude
import org.springframework.util.Assert
@@ -28,6 +29,7 @@ import org.springframework.util.Assert
* @since 1.0
*/
@JsonIgnoreProperties(["default", "all"])
+@JsonInclude(JsonInclude.Include.NON_NULL)
abstract class ServiceCapability {
final String id
diff --git a/initializr/src/main/groovy/io/spring/initializr/web/AbstractInitializrController.groovy b/initializr/src/main/groovy/io/spring/initializr/web/AbstractInitializrController.groovy
index 7467c10d..b5e7e3b4 100644
--- a/initializr/src/main/groovy/io/spring/initializr/web/AbstractInitializrController.groovy
+++ b/initializr/src/main/groovy/io/spring/initializr/web/AbstractInitializrController.groovy
@@ -55,7 +55,7 @@ abstract class AbstractInitializrController {
/**
* Generate a full URL of the service, mostly for use in templates.
- * @see io.spring.initializr.InitializrConfiguration.Env#forceSsl
+ * @see io.spring.initializr.metadata.InitializrConfiguration.Env#forceSsl
*/
protected String generateAppUrl() {
def builder = ServletUriComponentsBuilder.fromCurrentServletMapping()
diff --git a/initializr/src/main/resources/templates/starter-build.gradle b/initializr/src/main/resources/templates/starter-build.gradle
index 1b231b43..7941a37f 100644
--- a/initializr/src/main/resources/templates/starter-build.gradle
+++ b/initializr/src/main/resources/templates/starter-build.gradle
@@ -49,6 +49,13 @@ dependencies {<% compileDependencies.each { %>
testCompile("org.springframework.boot:spring-boot-starter-test") <% testDependencies.each { %>
testCompile("${it.groupId}:${it.artifactId}${it.version ? ":$it.version" : ""}")<% } %>
}
+<% if (boms) { %>
+dependencyManagement {
+ imports { <% boms.each { %>
+ mavenBom "${it.groupId}:${it.artifactId}${it.version ? ":$it.version" : ""}" <% } %>
+ }
+}
+<% } %>
eclipse {
classpath {
diff --git a/initializr/src/main/resources/templates/starter-pom.xml b/initializr/src/main/resources/templates/starter-pom.xml
index 34cf9890..8e3db099 100644
--- a/initializr/src/main/resources/templates/starter-pom.xml
+++ b/initializr/src/main/resources/templates/starter-pom.xml
@@ -64,7 +64,19 @@
test
<% } %>
-
+ <% if (boms) { %>
+
+ <% boms.each { %>
+
+ ${it.groupId}
+ ${it.artifactId}
+ ${it.version}
+ pom
+ import
+ <% } %>
+
+
+ <% } %>
diff --git a/initializr/src/test/groovy/io/spring/initializr/generator/ProjectGeneratorTests.groovy b/initializr/src/test/groovy/io/spring/initializr/generator/ProjectGeneratorTests.groovy
index c31ce7c3..98ff14e3 100644
--- a/initializr/src/test/groovy/io/spring/initializr/generator/ProjectGeneratorTests.groovy
+++ b/initializr/src/test/groovy/io/spring/initializr/generator/ProjectGeneratorTests.groovy
@@ -326,6 +326,46 @@ class ProjectGeneratorTests {
.doesNotContain("apply plugin: 'io.spring.dependency-management'")
}
+ @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()
+ projectGenerator.metadata = 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()
+ projectGenerator.metadata = metadata
+ def request = createProjectRequest('foo', 'bar')
+ generateMavenPom(request).hasDependency(foo)
+ .hasBom('org.acme', 'the-bom', '1.2.3')
+ .hasBomsCount(1)
+ }
+
+ @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()
+ projectGenerator.metadata = metadata
+ def request = createProjectRequest('foo')
+ generateGradleBuild(request)
+ .contains("dependencyManagement {")
+ .contains("imports {")
+ .contains("mavenBom \"org.acme:foo-bom:1.2.3\"")
+ }
+
PomAssert generateMavenPom(ProjectRequest request) {
def content = new String(projectGenerator.generateMavenPom(request))
new PomAssert(content).validateProjectRequest(request)
diff --git a/initializr/src/test/groovy/io/spring/initializr/InitializrConfigurationTests.groovy b/initializr/src/test/groovy/io/spring/initializr/metadata/InitializrConfigurationTests.groovy
similarity index 97%
rename from initializr/src/test/groovy/io/spring/initializr/InitializrConfigurationTests.groovy
rename to initializr/src/test/groovy/io/spring/initializr/metadata/InitializrConfigurationTests.groovy
index 475ae105..366a809d 100644
--- a/initializr/src/test/groovy/io/spring/initializr/InitializrConfigurationTests.groovy
+++ b/initializr/src/test/groovy/io/spring/initializr/metadata/InitializrConfigurationTests.groovy
@@ -14,8 +14,9 @@
* limitations under the License.
*/
-package io.spring.initializr
+package io.spring.initializr.metadata
+import io.spring.initializr.metadata.InitializrConfiguration
import org.junit.Test
import static org.junit.Assert.assertEquals
diff --git a/initializr/src/test/groovy/io/spring/initializr/metadata/InitializrMetadataBuilderTests.groovy b/initializr/src/test/groovy/io/spring/initializr/metadata/InitializrMetadataBuilderTests.groovy
index 71d4e405..31941796 100644
--- a/initializr/src/test/groovy/io/spring/initializr/metadata/InitializrMetadataBuilderTests.groovy
+++ b/initializr/src/test/groovy/io/spring/initializr/metadata/InitializrMetadataBuilderTests.groovy
@@ -16,7 +16,6 @@
package io.spring.initializr.metadata
-import io.spring.initializr.InitializrConfiguration
import org.junit.Test
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean
@@ -86,6 +85,26 @@ class InitializrMetadataBuilderTests {
assertEquals 'org.acme.demo', metadata.packageName.content
}
+ @Test
+ void mergeMetadataWithBom() {
+ def metadata = InitializrMetadataBuilder.create().withInitializrMetadata(
+ new ClassPathResource('metadata/service/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 mergeConfigurationDisabledByDefault() {
def config = load(new ClassPathResource("application-test-default.yml"))
@@ -116,13 +135,6 @@ class InitializrMetadataBuilderTests {
assertEquals false, actualEnv.forceSsl
}
- 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()
- }
-
@Test
void addDependencyInCustomizer() {
def group = new DependencyGroup(name: 'Extra')
@@ -138,6 +150,12 @@ class InitializrMetadataBuilderTests {
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 =
diff --git a/initializr/src/test/groovy/io/spring/initializr/metadata/InitializrMetadataTests.groovy b/initializr/src/test/groovy/io/spring/initializr/metadata/InitializrMetadataTests.groovy
new file mode 100644
index 00000000..aa57ae75
--- /dev/null
+++ b/initializr/src/test/groovy/io/spring/initializr/metadata/InitializrMetadataTests.groovy
@@ -0,0 +1,45 @@
+/*
+ * 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 io.spring.initializr.test.InitializrMetadataTestBuilder
+import org.junit.Rule
+import org.junit.Test
+import org.junit.rules.ExpectedException
+
+/**
+ * @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()
+ }
+
+}
diff --git a/initializr/src/test/groovy/io/spring/initializr/test/InitializrMetadataTestBuilder.groovy b/initializr/src/test/groovy/io/spring/initializr/test/InitializrMetadataTestBuilder.groovy
index 36a33e77..cf9fda16 100644
--- a/initializr/src/test/groovy/io/spring/initializr/test/InitializrMetadataTestBuilder.groovy
+++ b/initializr/src/test/groovy/io/spring/initializr/test/InitializrMetadataTestBuilder.groovy
@@ -16,6 +16,7 @@
package io.spring.initializr.test
+import io.spring.initializr.metadata.BillOfMaterials
import io.spring.initializr.metadata.DefaultMetadataElement
import io.spring.initializr.metadata.Dependency
import io.spring.initializr.metadata.DependencyGroup
@@ -23,7 +24,6 @@ import io.spring.initializr.metadata.InitializrMetadata
import io.spring.initializr.metadata.InitializrMetadataBuilder
import io.spring.initializr.metadata.Type
-
/**
* Easily create a {@link InitializrMetadata} instance for testing purposes.
*
@@ -140,4 +140,13 @@ class InitializrMetadataTestBuilder {
this
}
+ InitializrMetadataTestBuilder addBom(String id, String groupId, String artifactId, String version) {
+ builder.withCustomizer {
+ BillOfMaterials bom = new BillOfMaterials(
+ groupId: groupId, artifactId: artifactId, version: version)
+ it.configuration.env.boms[id] = bom
+ }
+ this
+ }
+
}
\ No newline at end of file
diff --git a/initializr/src/test/groovy/io/spring/initializr/test/PomAssert.groovy b/initializr/src/test/groovy/io/spring/initializr/test/PomAssert.groovy
index a07343ea..1ae7a739 100644
--- a/initializr/src/test/groovy/io/spring/initializr/test/PomAssert.groovy
+++ b/initializr/src/test/groovy/io/spring/initializr/test/PomAssert.groovy
@@ -17,6 +17,7 @@
package io.spring.initializr.test
import io.spring.initializr.generator.ProjectRequest
+import io.spring.initializr.metadata.BillOfMaterials
import io.spring.initializr.metadata.Dependency
import org.custommonkey.xmlunit.SimpleNamespaceContext
import org.custommonkey.xmlunit.XMLUnit
@@ -39,6 +40,7 @@ class PomAssert {
final XpathEngine eng
final Document doc
final Map dependencies = [:]
+ final Map boms = [:]
PomAssert(String content) {
eng = XMLUnit.newXpathEngine()
@@ -48,6 +50,7 @@ class PomAssert {
eng.namespaceContext = namespaceContext
doc = XMLUnit.buildControlDocument(content)
parseDependencies()
+ parseBoms()
}
/**
@@ -135,7 +138,7 @@ class PomAssert {
}
PomAssert hasDependency(Dependency expected) {
- def id = generateId(expected.groupId, expected.artifactId)
+ def id = generateDependencyId(expected.groupId, expected.artifactId)
def dependency = dependencies[id]
assertNotNull "No dependency found with '$id' --> ${dependencies.keySet()}", dependency
if (expected.version) {
@@ -147,6 +150,20 @@ class PomAssert {
this
}
+ PomAssert hasBom(String groupId, String artifactId, String version) {
+ def id = generateBomId(groupId, artifactId)
+ def bom = boms[id]
+ assertNotNull "No BOM found with '$id' --> ${boms.keySet()}", bom
+ assertEquals "Wrong version for $bom", version, bom.version
+ this
+ }
+
+ PomAssert hasBomsCount(int count) {
+ assertEquals "Wrong number of declared boms -->'${boms.keySet()}",
+ count, boms.size()
+ this
+ }
+
PomAssert hasNoRepository() {
assertEquals 0, eng.getMatchingNodes(createRootNodeXPath('repositories'), doc).length
this
@@ -216,7 +233,50 @@ class PomAssert {
}
}
- private static String generateId(String groupId, String artifactId) {
+ private def parseBoms() {
+ def nodes = eng.getMatchingNodes(createRootNodeXPath('dependencyManagement/pom:dependencies/pom:dependency'), doc)
+ for (int i = 0; i < nodes.length; i++) {
+ def item = nodes.item(i)
+ if (item instanceof Element) {
+ def element = (Element) item
+ def type = element.getElementsByTagName('type')
+ def scope = element.getElementsByTagName('scope')
+ if (isBom(type, scope)) {
+ def bom = new BillOfMaterials()
+ def groupId = element.getElementsByTagName('groupId')
+ if (groupId.length > 0) {
+ bom.groupId = groupId.item(0).textContent
+ }
+ def artifactId = element.getElementsByTagName('artifactId')
+ if (artifactId.length > 0) {
+ bom.artifactId = artifactId.item(0).textContent
+ }
+ def version = element.getElementsByTagName('version')
+ if (version.length > 0) {
+ bom.version = version.item(0).textContent
+ }
+ def id = generateBomId(bom.groupId, bom.artifactId)
+ assertFalse("Duplicate BOM with id $id", boms.containsKey(id))
+ boms[id] = bom
+ }
+ }
+ }
+ }
+
+ private static boolean isBom(def type, def scope) {
+ if (type.length == 0 || scope.length == 0) {
+ return false
+ }
+ String typeValue = type.item(0).textContent
+ String scopeValue = scope.item(0).textContent
+ return "pom".equals(typeValue) && "import".equals(scopeValue)
+ }
+
+ private static String generateBomId(def groupId, def artifactId) {
+ "$groupId:$artifactId"
+ }
+
+ private static String generateDependencyId(String groupId, String artifactId) {
def dependency = new Dependency()
dependency.groupId = groupId
dependency.artifactId = artifactId
diff --git a/initializr/src/test/resources/metadata/service/test-bom.json b/initializr/src/test/resources/metadata/service/test-bom.json
new file mode 100644
index 00000000..448efecd
--- /dev/null
+++ b/initializr/src/test/resources/metadata/service/test-bom.json
@@ -0,0 +1,19 @@
+{
+ "configuration": {
+ "env": {
+ "forceSsl": false,
+ "boms": {
+ "my-bom": {
+ "groupId": "org.acme",
+ "artifactId": "my-bom",
+ "version": "1.2.3.RELEASE"
+ },
+ "another-bom": {
+ "groupId": "org.acme",
+ "artifactId": "another-bom",
+ "version": "4.5.6.RELEASE"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/initializr/src/test/resources/metadata/service/test-default.json b/initializr/src/test/resources/metadata/service/test-default.json
index 111aea58..b7670678 100644
--- a/initializr/src/test/resources/metadata/service/test-default.json
+++ b/initializr/src/test/resources/metadata/service/test-default.json
@@ -1,7 +1,6 @@
{
"artifactId": {
"content": "demo",
- "description": null,
"id": "artifactId",
"type": "TEXT"
},
@@ -23,13 +22,13 @@
"name": "1.0.2"
}
],
- "description": null,
"id": "bootVersion",
"type": "SINGLE_SELECT"
},
"configuration": {
"env": {
"artifactRepository": "https://repo.spring.io/release/",
+ "boms": {},
"fallbackApplicationName": "Application",
"forceSsl": true,
"invalidApplicationNames": [
@@ -51,33 +50,25 @@
"groupId": "org.springframework.boot",
"id": "web",
"name": "Web",
- "scope": "compile",
- "version": null,
- "versionRange": null
+ "scope": "compile"
},
{
"aliases": [],
"artifactId": "spring-boot-starter-security",
- "description": null,
"facets": [],
"groupId": "org.springframework.boot",
"id": "security",
"name": "Security",
- "scope": "compile",
- "version": null,
- "versionRange": null
+ "scope": "compile"
},
{
"aliases": ["jpa"],
"artifactId": "spring-boot-starter-data-jpa",
- "description": null,
"facets": [],
"groupId": "org.springframework.boot",
"id": "data-jpa",
"name": "Data JPA",
- "scope": "compile",
- "version": null,
- "versionRange": null
+ "scope": "compile"
}
],
"name": "Core"
@@ -87,31 +78,26 @@
{
"aliases": [],
"artifactId": "foo",
- "description": null,
"facets": [],
"groupId": "org.acme",
"id": "org.acme:foo",
"name": "Foo",
"scope": "compile",
- "version": "1.3.5",
- "versionRange": null
+ "version": "1.3.5"
},
{
"aliases": [],
"artifactId": "bar",
- "description": null,
"facets": [],
"groupId": "org.acme",
"id": "org.acme:bar",
"name": "Bar",
"scope": "compile",
- "version": "2.1.0",
- "versionRange": null
+ "version": "2.1.0"
},
{
"aliases": [],
"artifactId": "biz",
- "description": null,
"facets": [],
"groupId": "org.acme",
"id": "org.acme:biz",
@@ -123,7 +109,6 @@
{
"aliases": [],
"artifactId": "bur",
- "description": null,
"facets": [],
"groupId": "org.acme",
"id": "org.acme:bur",
@@ -135,32 +120,26 @@
{
"aliases": [],
"artifactId": "my-api",
- "description": null,
"facets": [],
"groupId": "org.acme",
"id": "my-api",
"name": "My API",
- "scope": "provided",
- "version": null,
- "versionRange": null
+ "scope": "provided"
}
],
"name": "Other"
}
],
- "description": null,
"id": "dependencies",
"type": "HIERARCHICAL_MULTI_SELECT"
},
"description": {
"content": "Demo project for Spring Boot",
- "description": null,
"id": "description",
"type": "TEXT"
},
"groupId": {
"content": "org.test",
- "description": null,
"id": "groupId",
"type": "TEXT"
},
@@ -182,7 +161,6 @@
"name": "1.8"
}
],
- "description": null,
"id": "javaVersion",
"type": "SINGLE_SELECT"
},
@@ -199,19 +177,16 @@
"name": "Java"
}
],
- "description": null,
"id": "language",
"type": "SINGLE_SELECT"
},
"name": {
"content": "demo",
- "description": null,
"id": "name",
"type": "TEXT"
},
"packageName": {
"content": "demo",
- "description": null,
"id": "packageName",
"type": "TEXT"
},
@@ -228,7 +203,6 @@
"name": "War"
}
],
- "description": null,
"id": "packaging",
"type": "SINGLE_SELECT"
},
@@ -283,13 +257,11 @@
}
}
],
- "description": null,
"id": "type",
"type": "ACTION"
},
"version": {
"content": "0.0.1-SNAPSHOT",
- "description": null,
"id": "version",
"type": "TEXT"
}