diff --git a/initializr/src/main/groovy/io/spring/initializr/InitializrConfiguration.groovy b/initializr/src/main/groovy/io/spring/initializr/InitializrConfiguration.groovy
new file mode 100644
index 00000000..8e538181
--- /dev/null
+++ b/initializr/src/main/groovy/io/spring/initializr/InitializrConfiguration.groovy
@@ -0,0 +1,120 @@
+/*
+ * 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
+
+/**
+ * Various configuration options used by the service.
+ *
+ * @author Stephane Nicoll
+ * @since 1.0
+ */
+class InitializrConfiguration {
+
+ final Env env = new Env()
+
+ /**
+ * Generate a suitable application mame 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
+ }
+ }
+
+ 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 meta-data url of the Spring Boot project
+ */
+ String springBootMetadataUrl = 'https://spring.io/project_metadata/spring-boot'
+
+ /**
+ * 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 {@link #fallbackApplicationName} should be used instead.
+ */
+ List invalidApplicationNames = [
+ 'SpringApplication',
+ 'SpringBootApplication'
+ ]
+
+ /**
+ * Force SSL support. When enabled, any access using http generate https links.
+ */
+ boolean forceSsl = true
+
+ void setArtifactRepository(String artifactRepository) {
+ if (!artifactRepository.endsWith('/')) {
+ artifactRepository = artifactRepository + '/'
+ }
+ this.artifactRepository = artifactRepository
+ }
+
+ }
+}
diff --git a/initializr/src/main/groovy/io/spring/initializr/InitializrMetadata.groovy b/initializr/src/main/groovy/io/spring/initializr/InitializrMetadata.groovy
deleted file mode 100644
index 5d2e4d34..00000000
--- a/initializr/src/main/groovy/io/spring/initializr/InitializrMetadata.groovy
+++ /dev/null
@@ -1,480 +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
-
-import javax.annotation.PostConstruct
-
-import groovy.transform.ToString
-import groovy.util.logging.Slf4j
-import io.spring.initializr.mapper.InitializrMetadataJsonMapper
-import io.spring.initializr.mapper.InitializrMetadataV21JsonMapper
-import io.spring.initializr.mapper.InitializrMetadataV2JsonMapper
-import io.spring.initializr.support.InvalidVersionException
-import io.spring.initializr.support.VersionRange
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.context.properties.ConfigurationProperties
-
-/**
- * The metadata using by the initializr, that is:
- *
- *
- * - Known dependencies gathered in group
- * - The build types supported by the service
- * - Supported Java versions
- * - Supported language
- * - Supported Spring Boot versions
- * - Default settings used to generate the project
- * - Environment related settings
- *
- *
- * @author Stephane Nicoll
- * @since 1.0
- */
-@ConfigurationProperties(prefix = 'initializr', ignoreUnknownFields = false)
-@Slf4j
-class InitializrMetadata {
-
- final List dependencies = []
-
- final List types = []
-
- final List packagings = []
-
- final List javaVersions = []
-
- final List languages = []
-
- final List bootVersions = []
-
- final Defaults defaults = new Defaults()
-
- final Env env = new Env()
-
- private final Map indexedDependencies = [:]
-
- @Autowired(required = false)
- List customizers = []
-
- /**
- * Return the {@link Dependency} with the specified id or {@code null} if
- * no such dependency exists.
- */
- Dependency getDependency(String id) {
- indexedDependencies[id]
- }
-
- /**
- * Return all dependencies as a flat collection
- */
- Collection getAllDependencies() {
- indexedDependencies.values()
- }
-
- /**
- * Return the {@link Type} with the specified id or {@code null} if no
- * such type exists.
- */
- Type getType(String id) {
- for (it in this.types) {
- if (id.equals(it.id) || id.equals(it.stsId)) {
- return it
- }
- }
- return null
- }
-
- /**
- * Create an URL suitable to download Spring Boot cli for the specified version and extension.
- */
- String createCliDistributionURl(String extension) {
- env.artifactRepository + "org/springframework/boot/spring-boot-cli/" +
- "$defaults.bootVersion/spring-boot-cli-$defaults.bootVersion-bin.$extension"
- }
-
- /**
- * Generate a suitable application mame 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
- }
- }
-
- /**
- * Initializes a {@link ProjectRequest} instance with the defaults
- * defined in this instance.
- */
- void initializeProjectRequest(ProjectRequest request) {
- defaults.properties.each { key, value ->
- if (request.hasProperty(key) && !(key in ['class', 'metaClass'])) {
- request[key] = value
- }
- }
- request
- }
-
- /**
- * Merge this instance with the specified content.
- */
- void merge(List bootVersions) {
- if (bootVersions) {
- synchronized (this.bootVersions) {
- this.bootVersions.clear()
- this.bootVersions.addAll(bootVersions)
- }
- }
- refreshDefaults()
- }
-
- /**
- * Generate a JSON representation of the current metadata
- * @param version the meta-data version
- * @param appUrl the application url
- */
- String generateJson(InitializrMetadataVersion version, String appUrl) {
- getJsonMapper(version).write(this, appUrl)
- }
-
- /**
- * Initialize and validate the configuration.
- */
- @PostConstruct
- void validate() {
-
- customizers.each { customizer ->
- customizer.customize(this)
- }
-
- dependencies.each { group ->
- group.content.each { dependency ->
- validateDependency(dependency)
- indexDependency(dependency.id, dependency)
- for (String alias : dependency.aliases) {
- indexDependency(alias, dependency)
- }
- }
- }
- env.validate()
-
- refreshDefaults()
- }
-
- private void refreshDefaults() {
- defaults.type = getDefault(types)
- defaults.packaging = getDefault(packagings)
- defaults.javaVersion = getDefault(javaVersions)
- defaults.language = getDefault(languages)
- defaults.bootVersion = getDefault(bootVersions)
- }
-
- 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
- }
-
- static void validateDependency(Dependency dependency) {
- def id = dependency.id
- if (id == null) {
- if (!dependency.hasCoordinates()) {
- throw new InvalidInitializrMetadataException(
- 'Invalid dependency, should have at least an id or a groupId/artifactId pair.')
- }
- dependency.generateId()
- } else if (!dependency.hasCoordinates()) {
- // Let's build the coordinates from the id
- def st = new StringTokenizer(id, ':')
- if (st.countTokens() == 1) { // assume spring-boot-starter
- dependency.asSpringBootStarter(id)
- } else if (st.countTokens() == 2 || st.countTokens() == 3) {
- dependency.groupId = st.nextToken()
- dependency.artifactId = st.nextToken()
- if (st.hasMoreTokens()) {
- dependency.version = st.nextToken()
- }
- } else {
- throw new InvalidInitializrMetadataException(
- "Invalid dependency, id should have the form groupId:artifactId[:version] but got $id")
- }
- }
- if (dependency.versionRange) {
- try {
- VersionRange.parse(dependency.versionRange)
- } catch (InvalidVersionException ex) {
- throw new InvalidInitializrMetadataException("Invalid version range '$dependency.versionRange' for " +
- "dependency with id '$dependency.id'")
- }
- }
- }
-
- static def getDefault(List elements) {
- for (DefaultIdentifiableElement element : elements) {
- if (element.default) {
- return element.id
- }
- }
- log.warn("No default found amongst $elements")
- return (elements.isEmpty() ? null : elements.get(0).id)
- }
-
- private static InitializrMetadataJsonMapper getJsonMapper(InitializrMetadataVersion version) {
- switch(version) {
- case InitializrMetadataVersion.V2: return new InitializrMetadataV2JsonMapper();
- default: return new InitializrMetadataV21JsonMapper();
- }
- }
-
- 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
- }
-
- static class DependencyGroup {
-
- String name
-
- final List content = []
-
- }
-
- @ToString(ignoreNulls = true, includePackage = false)
- static class Dependency extends IdentifiableElement {
-
- static final String SCOPE_COMPILE = 'compile'
- 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_PROVIDED, SCOPE_TEST]
-
- List aliases = []
-
- List facets = []
-
- String groupId
-
- String artifactId
-
- String version
-
- String scope = SCOPE_COMPILE
-
- String description
-
- String versionRange
-
- 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
- }
-
- /**
- * 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()
- }
- }
-
- static class Type extends DefaultIdentifiableElement {
-
- String description
-
- @Deprecated
- String stsId
-
- String action
-
- void setAction(String action) {
- String actionToUse = action
- if (!actionToUse.startsWith("/")) {
- actionToUse = "/" + actionToUse
- }
- this.action = actionToUse
- }
-
- final Map tags = [:]
- }
-
- static class Packaging extends DefaultIdentifiableElement {
- }
-
- static class JavaVersion extends DefaultIdentifiableElement {
- }
-
- static class Language extends DefaultIdentifiableElement {
- }
-
- static class BootVersion extends DefaultIdentifiableElement {
- }
-
- static class Defaults {
-
- static final String DEFAULT_NAME = 'demo'
-
- String groupId = 'org.test'
- String artifactId
- String version = '0.0.1-SNAPSHOT'
- String name = DEFAULT_NAME
- String description = 'Demo project for Spring Boot'
- String packageName
- String type
- String packaging
- String javaVersion
- String language
- String bootVersion
-
- /**
- * Return the artifactId or the name of the project if none is set.
- */
- String getArtifactId() {
- artifactId == null ? name : artifactId
- }
-
- /**
- * Return the package name or the name of the project if none is set
- */
- String getPackageName() {
- packageName == null ? name.replace('-', '.') : packageName
- }
-
- }
-
- /**
- * Defines additional environment settings
- */
- static class Env {
-
- String artifactRepository = 'https://repo.spring.io/release/'
-
- String springBootMetadataUrl = 'https://spring.io/project_metadata/spring-boot'
-
- /**
- * 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 {@link #fallbackApplicationName} should be used instead.
- */
- List invalidApplicationNames = ['SpringApplication', 'SpringBootApplication']
-
- boolean forceSsl = true
-
- void validate() {
- if (!artifactRepository.endsWith('/')) {
- artifactRepository = artifactRepository + '/'
- }
- }
-
- }
-
- static class DefaultIdentifiableElement extends IdentifiableElement {
-
- private boolean defaultValue
-
- void setDefault(boolean defaultValue) {
- this.defaultValue = defaultValue
- }
-
- boolean isDefault() {
- this.defaultValue
- }
- }
-
- static class IdentifiableElement {
-
- String name
-
- String id
-
- String getName() {
- (name ?: id)
- }
- }
-}
diff --git a/initializr/src/main/groovy/io/spring/initializr/InitializrAutoConfiguration.groovy b/initializr/src/main/groovy/io/spring/initializr/config/InitializrAutoConfiguration.groovy
similarity index 81%
rename from initializr/src/main/groovy/io/spring/initializr/InitializrAutoConfiguration.groovy
rename to initializr/src/main/groovy/io/spring/initializr/config/InitializrAutoConfiguration.groovy
index 0bc64123..2b2c000e 100644
--- a/initializr/src/main/groovy/io/spring/initializr/InitializrAutoConfiguration.groovy
+++ b/initializr/src/main/groovy/io/spring/initializr/config/InitializrAutoConfiguration.groovy
@@ -14,11 +14,18 @@
* limitations under the License.
*/
-package io.spring.initializr
+package io.spring.initializr.config
import java.util.concurrent.TimeUnit
import com.google.common.cache.CacheBuilder
+import io.spring.initializr.generator.ProjectGenerationMetricsListener
+import io.spring.initializr.generator.ProjectGenerator
+import io.spring.initializr.metadata.InitializrMetadata
+import io.spring.initializr.metadata.InitializrMetadataBuilder
+import io.spring.initializr.metadata.InitializrMetadataProvider
+import io.spring.initializr.metadata.InitializrProperties
+import io.spring.initializr.support.DefaultInitializrMetadataProvider
import io.spring.initializr.web.MainController
import io.spring.initializr.web.WebConfig
@@ -47,7 +54,7 @@ import org.springframework.context.annotation.Configuration
*/
@Configuration
@EnableCaching
-@EnableConfigurationProperties(InitializrMetadata)
+@EnableConfigurationProperties(InitializrProperties)
class InitializrAutoConfiguration {
@Autowired
@@ -72,6 +79,12 @@ class InitializrAutoConfiguration {
generator
}
+ @Bean
+ @ConditionalOnMissingBean
+ InitializrMetadata initializrMetadata(InitializrProperties properties) {
+ new InitializrMetadataBuilder().fromConfiguration(properties).build()
+ }
+
@Bean
@ConditionalOnMissingBean(InitializrMetadataProvider)
InitializrMetadataProvider initializrMetadataProvider(InitializrMetadata metadata) {
diff --git a/initializr/src/main/groovy/io/spring/initializr/CommandLineHelpGenerator.groovy b/initializr/src/main/groovy/io/spring/initializr/generator/CommandLineHelpGenerator.groovy
similarity index 88%
rename from initializr/src/main/groovy/io/spring/initializr/CommandLineHelpGenerator.groovy
rename to initializr/src/main/groovy/io/spring/initializr/generator/CommandLineHelpGenerator.groovy
index 008d6f36..21202ea2 100644
--- a/initializr/src/main/groovy/io/spring/initializr/CommandLineHelpGenerator.groovy
+++ b/initializr/src/main/groovy/io/spring/initializr/generator/CommandLineHelpGenerator.groovy
@@ -14,11 +14,13 @@
* limitations under the License.
*/
-package io.spring.initializr
+package io.spring.initializr.generator
-import io.spring.initializr.support.VersionRange
+import io.spring.initializr.metadata.InitializrMetadata
+import io.spring.initializr.metadata.Type
+import io.spring.initializr.util.VersionRange
-import static io.spring.initializr.support.GroovyTemplate.template
+import static io.spring.initializr.util.GroovyTemplate.template
/**
* Generate help pages for command-line clients.
@@ -86,13 +88,8 @@ class CommandLineHelpGenerator {
model['dependencies'] = generateDependencyTable(metadata)
model['types'] = generateTypeTable(metadata, 'Rel', false)
- Map defaults = [:]
- metadata.defaults.properties.each {
- if (!(it.key in ['class', 'metaClass', 'DEFAULT_NAME'])) {
- defaults[it.key] = it.value
- }
- }
- defaults['applicationName'] = metadata.generateApplicationName(metadata.defaults.name)
+ Map defaults = metadata.defaults()
+ defaults['applicationName'] = metadata.configuration.generateApplicationName(metadata.name.content)
defaults['baseDir'] = 'no base dir'
defaults['dependencies'] = 'none'
@@ -119,12 +116,7 @@ class CommandLineHelpGenerator {
model['types'] = generateTypeTable(metadata, 'Id', true)
- Map defaults = [:]
- metadata.defaults.properties.sort().each {
- if (!(it.key in ['class', 'metaClass', 'DEFAULT_NAME'])) {
- defaults[it.key] = it.value
- }
- }
+ Map defaults = metadata.defaults()
Map parametersDescription = buildParametersDescription()
String[][] parameterTable = new String[defaults.size() + 1][];
parameterTable[0] = ["Id", "Description", "Default value"]
@@ -140,9 +132,9 @@ class CommandLineHelpGenerator {
}
protected String generateDependencyTable(InitializrMetadata metadata) {
- String[][] dependencyTable = new String[metadata.allDependencies.size() + 1][];
+ String[][] dependencyTable = new String[metadata.dependencies.all.size() + 1][];
dependencyTable[0] = ["Id", "Description", "Required version"]
- new ArrayList(metadata.allDependencies).sort { a, b -> a.id <=> b.id }
+ new ArrayList(metadata.dependencies.all).sort { a, b -> a.id <=> b.id }
.eachWithIndex { dep, i ->
String[] data = new String[3]
data[0] = dep.id
@@ -154,16 +146,16 @@ class CommandLineHelpGenerator {
}
protected String generateTypeTable(InitializrMetadata metadata, String linkHeader, boolean addTags) {
- String[][] typeTable = new String[metadata.types.size() + 1][];
+ 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).sort { a, b -> a.id <=> b.id }.eachWithIndex { type, i ->
+ new ArrayList<>(metadata.types.content).sort { a, b -> a.id <=> b.id }.eachWithIndex { type, i ->
String[] data = new String[typeTable[0].length]
- data[0] = (metadata.defaults.type.equals(type.id) ? type.id + " *" : type.id)
+ data[0] = (type.default ? type.id + " *" : type.id)
data[1] = type.description ?: type.name
if (addTags) {
data[2] = buildTagRepresentation(type)
@@ -205,7 +197,7 @@ class CommandLineHelpGenerator {
}
}
- private static String buildTagRepresentation(InitializrMetadata.Type type) {
+ private static String buildTagRepresentation(Type type) {
if (type.tags.isEmpty()) {
return "";
}
diff --git a/initializr/src/main/groovy/io/spring/initializr/InvalidProjectRequestException.groovy b/initializr/src/main/groovy/io/spring/initializr/generator/InvalidProjectRequestException.groovy
similarity index 87%
rename from initializr/src/main/groovy/io/spring/initializr/InvalidProjectRequestException.groovy
rename to initializr/src/main/groovy/io/spring/initializr/generator/InvalidProjectRequestException.groovy
index 2c3d4370..ff3ab2ce 100644
--- a/initializr/src/main/groovy/io/spring/initializr/InvalidProjectRequestException.groovy
+++ b/initializr/src/main/groovy/io/spring/initializr/generator/InvalidProjectRequestException.groovy
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2014 the original author or authors.
+ * 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.
@@ -14,9 +14,10 @@
* limitations under the License.
*/
-package io.spring.initializr
+package io.spring.initializr.generator
import groovy.transform.InheritConstructors
+import io.spring.initializr.InitializrException
import org.springframework.http.HttpStatus
import org.springframework.web.bind.annotation.ResponseStatus
diff --git a/initializr/src/main/groovy/io/spring/initializr/ProjectGenerationListener.groovy b/initializr/src/main/groovy/io/spring/initializr/generator/ProjectGenerationListener.groovy
similarity index 90%
rename from initializr/src/main/groovy/io/spring/initializr/ProjectGenerationListener.groovy
rename to initializr/src/main/groovy/io/spring/initializr/generator/ProjectGenerationListener.groovy
index 1b4d4ae5..23d80c8b 100644
--- a/initializr/src/main/groovy/io/spring/initializr/ProjectGenerationListener.groovy
+++ b/initializr/src/main/groovy/io/spring/initializr/generator/ProjectGenerationListener.groovy
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2014 the original author or authors.
+ * 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.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package io.spring.initializr
+package io.spring.initializr.generator
/**
* Interface to be implemented by components that need to be aware of project generation
diff --git a/initializr/src/main/groovy/io/spring/initializr/ProjectGenerationMetricsListener.groovy b/initializr/src/main/groovy/io/spring/initializr/generator/ProjectGenerationMetricsListener.groovy
similarity index 96%
rename from initializr/src/main/groovy/io/spring/initializr/ProjectGenerationMetricsListener.groovy
rename to initializr/src/main/groovy/io/spring/initializr/generator/ProjectGenerationMetricsListener.groovy
index 2c42ca1a..0d58d064 100644
--- a/initializr/src/main/groovy/io/spring/initializr/ProjectGenerationMetricsListener.groovy
+++ b/initializr/src/main/groovy/io/spring/initializr/generator/ProjectGenerationMetricsListener.groovy
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2014 the original author or authors.
+ * 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.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package io.spring.initializr
+package io.spring.initializr.generator
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.actuate.metrics.CounterService
diff --git a/initializr/src/main/groovy/io/spring/initializr/ProjectGenerator.groovy b/initializr/src/main/groovy/io/spring/initializr/generator/ProjectGenerator.groovy
similarity index 93%
rename from initializr/src/main/groovy/io/spring/initializr/ProjectGenerator.groovy
rename to initializr/src/main/groovy/io/spring/initializr/generator/ProjectGenerator.groovy
index 412c0a30..6cef4709 100644
--- a/initializr/src/main/groovy/io/spring/initializr/ProjectGenerator.groovy
+++ b/initializr/src/main/groovy/io/spring/initializr/generator/ProjectGenerator.groovy
@@ -14,17 +14,18 @@
* limitations under the License.
*/
-package io.spring.initializr
+package io.spring.initializr.generator
import groovy.util.logging.Slf4j
-import io.spring.initializr.support.Version
+import io.spring.initializr.metadata.Dependency
+import io.spring.initializr.metadata.InitializrMetadata
+import io.spring.initializr.util.Version
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.beans.factory.annotation.Value
import org.springframework.util.Assert
-import static io.spring.initializr.InitializrMetadata.Dependency.*
-import static io.spring.initializr.support.GroovyTemplate.template
+import static io.spring.initializr.util.GroovyTemplate.template
/**
* Generate a project based on the configured metadata.
@@ -174,10 +175,10 @@ class ProjectGenerator {
request.properties.each { model[it.key] = it.value }
- model['compileDependencies'] = filterDependencies(dependencies, SCOPE_COMPILE)
- model['runtimeDependencies'] = filterDependencies(dependencies, SCOPE_RUNTIME)
- model['providedDependencies'] = filterDependencies(dependencies, SCOPE_PROVIDED)
- model['testDependencies'] = filterDependencies(dependencies, SCOPE_TEST)
+ model['compileDependencies'] = filterDependencies(dependencies, Dependency.SCOPE_COMPILE)
+ model['runtimeDependencies'] = filterDependencies(dependencies, Dependency.SCOPE_RUNTIME)
+ model['providedDependencies'] = filterDependencies(dependencies, Dependency.SCOPE_PROVIDED)
+ model['testDependencies'] = filterDependencies(dependencies, Dependency.SCOPE_TEST)
// @SpringBootApplication available as from 1.2.0.RC1
model['useSpringBootApplication'] = VERSION_1_2_0_RC1
diff --git a/initializr/src/main/groovy/io/spring/initializr/ProjectRequest.groovy b/initializr/src/main/groovy/io/spring/initializr/generator/ProjectRequest.groovy
similarity index 78%
rename from initializr/src/main/groovy/io/spring/initializr/ProjectRequest.groovy
rename to initializr/src/main/groovy/io/spring/initializr/generator/ProjectRequest.groovy
index 101b20c4..23ab8309 100644
--- a/initializr/src/main/groovy/io/spring/initializr/ProjectRequest.groovy
+++ b/initializr/src/main/groovy/io/spring/initializr/generator/ProjectRequest.groovy
@@ -14,11 +14,14 @@
* limitations under the License.
*/
-package io.spring.initializr
+package io.spring.initializr.generator
import groovy.util.logging.Slf4j
-import io.spring.initializr.support.Version
-import io.spring.initializr.support.VersionRange
+import io.spring.initializr.metadata.Dependency
+import io.spring.initializr.metadata.InitializrMetadata
+import io.spring.initializr.metadata.Type
+import io.spring.initializr.util.Version
+import io.spring.initializr.util.VersionRange
/**
* A request to generate a project.
@@ -54,29 +57,40 @@ class ProjectRequest {
String baseDir
// Resolved dependencies based on the ids provided by either "style" or "dependencies"
- List resolvedDependencies
+ List resolvedDependencies
def facets = []
def build
+ /**
+ * Initializes this instance with the defaults defined in the specified {@link InitializrMetadata}.
+ */
+ void initialize(InitializrMetadata metadata) {
+ metadata.defaults().forEach { 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
resolvedDependencies = depIds.collect {
- def dependency = metadata.getDependency(it)
+ def dependency = metadata.dependencies.get(it)
if (dependency == null) {
if (it.contains(':')) {
throw new InvalidProjectRequestException("Unknown dependency '$it' check project metadata")
}
log.warn("No known dependency for style '$it' assuming spring-boot-starter")
- dependency = new InitializrMetadata.Dependency()
+ dependency = new Dependency()
dependency.asSpringBootStarter(it)
}
dependency
}
- String actualBootVersion = bootVersion ?: metadata.defaults.bootVersion
+ String actualBootVersion = bootVersion ?: metadata.bootVersions.default.id
Version requestedVersion = Version.parse(actualBootVersion)
resolvedDependencies.each {
it.facets.each {
@@ -94,7 +108,7 @@ class ProjectRequest {
}
if (this.type) {
- InitializrMetadata.Type type = metadata.getType(this.type)
+ Type type = metadata.types.get(this.type)
if (!type) {
throw new InvalidProjectRequestException("Unknown type '${this.type}' check project metadata")
}
@@ -105,7 +119,7 @@ class ProjectRequest {
}
if (!applicationName) {
- this.applicationName = metadata.generateApplicationName(this.name)
+ this.applicationName = metadata.configuration.generateApplicationName(this.name)
}
afterResolution(metadata)
@@ -117,7 +131,7 @@ class ProjectRequest {
protected afterResolution(InitializrMetadata metadata) {
if (packaging == 'war' && !hasWebFacet()) {
// Need to be able to bootstrap the web app
- resolvedDependencies << metadata.getDependency('web')
+ resolvedDependencies << metadata.dependencies.get('web')
facets << 'web'
}
if (resolvedDependencies.isEmpty()) {
@@ -130,7 +144,7 @@ class ProjectRequest {
* dependency
*/
protected addDefaultDependency() {
- def root = new InitializrMetadata.Dependency()
+ def root = new Dependency()
root.id = DEFAULT_STARTER
root.asSpringBootStarter('')
resolvedDependencies << root
diff --git a/initializr/src/main/groovy/io/spring/initializr/mapper/InitializrMetadataJsonMapper.groovy b/initializr/src/main/groovy/io/spring/initializr/mapper/InitializrMetadataJsonMapper.groovy
index 280c46f7..52d7964b 100644
--- a/initializr/src/main/groovy/io/spring/initializr/mapper/InitializrMetadataJsonMapper.groovy
+++ b/initializr/src/main/groovy/io/spring/initializr/mapper/InitializrMetadataJsonMapper.groovy
@@ -16,7 +16,7 @@
package io.spring.initializr.mapper
-import io.spring.initializr.InitializrMetadata
+import io.spring.initializr.metadata.InitializrMetadata
/**
* Generate a JSON representation of the metadata.
diff --git a/initializr/src/main/groovy/io/spring/initializr/mapper/InitializrMetadataV2JsonMapper.groovy b/initializr/src/main/groovy/io/spring/initializr/mapper/InitializrMetadataV2JsonMapper.groovy
index 93ee7e5b..01a679e7 100644
--- a/initializr/src/main/groovy/io/spring/initializr/mapper/InitializrMetadataV2JsonMapper.groovy
+++ b/initializr/src/main/groovy/io/spring/initializr/mapper/InitializrMetadataV2JsonMapper.groovy
@@ -1,14 +1,14 @@
/*
- * Copyright 2012-2014 the original author or authors.
+ * Copyright 2012-2015 the original author or authors.
*
- * Licensed under the Apache License, Version 2.0 (the 'License');
+ * 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,
+ * 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.
@@ -17,12 +17,12 @@
package io.spring.initializr.mapper
import groovy.json.JsonBuilder
-import io.spring.initializr.InitializrMetadata
+import io.spring.initializr.metadata.InitializrMetadata
+import io.spring.initializr.metadata.SingleSelectCapability
import org.springframework.hateoas.TemplateVariable
import org.springframework.hateoas.TemplateVariables
import org.springframework.hateoas.UriTemplate
-import org.springframework.util.StringUtils
/**
* A {@link InitializrMetadataJsonMapper} handling the meta-data format for v2.
@@ -54,19 +54,19 @@ class InitializrMetadataV2JsonMapper implements InitializrMetadataJsonMapper {
String write(InitializrMetadata metadata, String appUrl) {
JsonBuilder json = new JsonBuilder()
json {
- links(delegate, metadata.types, appUrl)
+ links(delegate, metadata.types.content, appUrl)
dependencies(delegate, metadata.dependencies)
- type(delegate, metadata.defaults.type, metadata.types)
- singleSelect(delegate, 'packaging', metadata.defaults.packaging, metadata.packagings)
- singleSelect(delegate, 'javaVersion', metadata.defaults.javaVersion, metadata.javaVersions)
- singleSelect(delegate, 'language', metadata.defaults.language, metadata.languages)
- singleSelect(delegate, 'bootVersion', metadata.defaults.bootVersion, metadata.bootVersions)
- text(delegate, 'groupId', metadata.defaults.groupId)
- text(delegate, 'artifactId', metadata.defaults.artifactId)
- text(delegate, 'version', metadata.defaults.version)
- text(delegate, 'name', metadata.defaults.name)
- text(delegate, 'description', metadata.defaults.description)
- text(delegate, 'packageName', metadata.defaults.packageName)
+ type(delegate, metadata.types)
+ singleSelect(delegate, metadata.packagings)
+ singleSelect(delegate, metadata.javaVersions)
+ singleSelect(delegate, metadata.languages)
+ singleSelect(delegate, metadata.bootVersions)
+ text(delegate, metadata.groupId)
+ text(delegate, metadata.artifactId)
+ text(delegate, metadata.version)
+ text(delegate, metadata.name)
+ text(delegate, metadata.description)
+ text(delegate, metadata.packageName)
}
json.toString()
}
@@ -94,44 +94,47 @@ class InitializrMetadataV2JsonMapper implements InitializrMetadataJsonMapper {
}
- protected dependencies(parent, groups) {
- parent.dependencies {
- type 'hierarchical-multi-select'
- values groups.collect {
+ protected dependencies(parent, capability) {
+ parent."$capability.id" {
+ type "$capability.type.name"
+ values capability.content.collect {
mapDependencyGroup(it)
}
}
}
- protected type(parent, defaultValue, dependencies) {
+ protected type(parent, capability) {
parent.type {
type 'action'
- if (defaultValue) {
- 'default' defaultValue
+ def defaultType = capability.default
+ if (defaultType) {
+ 'default' defaultType.id
}
- values dependencies.collect {
+ values capability.content.collect {
mapType(it)
}
}
}
- protected singleSelect(parent, name, defaultValue, itemValues) {
- parent."$name" {
- type 'single-select'
+ protected singleSelect(parent, SingleSelectCapability capability) {
+ parent."$capability.id" {
+ type "$capability.type.name"
+ def defaultValue = capability.default
if (defaultValue) {
- 'default' defaultValue
+ 'default' defaultValue.id
}
- values itemValues.collect {
+ values capability.content.collect {
mapValue(it)
}
}
}
- protected text(parent, name, value) {
- parent."$name" {
- type 'text'
- if (value) {
- 'default' value
+ protected text(parent, capability) {
+ parent."$capability.id" {
+ type "$capability.type.name"
+ def defaultValue = capability.content
+ if (defaultValue) {
+ 'default' defaultValue
}
}
}
diff --git a/initializr/src/main/groovy/io/spring/initializr/InitializrMetadataVersion.groovy b/initializr/src/main/groovy/io/spring/initializr/mapper/InitializrMetadataVersion.groovy
similarity index 97%
rename from initializr/src/main/groovy/io/spring/initializr/InitializrMetadataVersion.groovy
rename to initializr/src/main/groovy/io/spring/initializr/mapper/InitializrMetadataVersion.groovy
index 0ec58f5e..dfe8bbef 100644
--- a/initializr/src/main/groovy/io/spring/initializr/InitializrMetadataVersion.groovy
+++ b/initializr/src/main/groovy/io/spring/initializr/mapper/InitializrMetadataVersion.groovy
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package io.spring.initializr
+package io.spring.initializr.mapper
import org.springframework.http.MediaType
diff --git a/initializr/src/main/groovy/io/spring/initializr/metadata/DefaultMetadataElement.groovy b/initializr/src/main/groovy/io/spring/initializr/metadata/DefaultMetadataElement.groovy
new file mode 100644
index 00000000..0d9e4578
--- /dev/null
+++ b/initializr/src/main/groovy/io/spring/initializr/metadata/DefaultMetadataElement.groovy
@@ -0,0 +1,37 @@
+/*
+ * 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
+
+/**
+ * A {@link MetadataElement} that specifies if its
+ * the default for a given capability.
+ *
+ * @author Stephane Nicoll
+ * @since 1.0
+ */
+class DefaultMetadataElement extends MetadataElement {
+
+ private boolean defaultValue
+
+ void setDefault(boolean defaultValue) {
+ this.defaultValue = defaultValue
+ }
+
+ boolean isDefault() {
+ this.defaultValue
+ }
+}
diff --git a/initializr/src/main/groovy/io/spring/initializr/metadata/DependenciesCapability.groovy b/initializr/src/main/groovy/io/spring/initializr/metadata/DependenciesCapability.groovy
new file mode 100644
index 00000000..fcedeee9
--- /dev/null
+++ b/initializr/src/main/groovy/io/spring/initializr/metadata/DependenciesCapability.groovy
@@ -0,0 +1,73 @@
+/*
+ * 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
+
+/**
+ * A {@link ServiceCapability} listing the available dependencies defined as a
+ * {@link ServiceCapabilityType#HIERARCHICAL_MULTI_SELECT} capability.
+ *
+ * @author Stephane Nicoll
+ * @since 1.0
+ */
+class DependenciesCapability extends ServiceCapability> {
+
+ final List content = []
+
+ private final Map indexedDependencies = [:]
+
+ DependenciesCapability() {
+ super('dependencies', ServiceCapabilityType.HIERARCHICAL_MULTI_SELECT)
+ }
+
+ /**
+ * 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() {
+ indexedDependencies.clear()
+ content.each { group ->
+ group.content.each { dependency ->
+ 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/src/main/groovy/io/spring/initializr/metadata/Dependency.groovy b/initializr/src/main/groovy/io/spring/initializr/metadata/Dependency.groovy
new file mode 100644
index 00000000..2c6118e5
--- /dev/null
+++ b/initializr/src/main/groovy/io/spring/initializr/metadata/Dependency.groovy
@@ -0,0 +1,142 @@
+/*
+ * 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
+import io.spring.initializr.util.InvalidVersionException
+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
+ * @since 1.0
+ */
+@ToString(ignoreNulls = true, includePackage = false)
+class Dependency extends MetadataElement {
+
+ static final String SCOPE_COMPILE = 'compile'
+ 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_PROVIDED,
+ SCOPE_TEST
+ ]
+
+ List aliases = []
+
+ List facets = []
+
+ String groupId
+
+ String artifactId
+
+ String version
+
+ String scope = SCOPE_COMPILE
+
+ String description
+
+ String versionRange
+
+ 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")
+ }
+ }
+ if (versionRange) {
+ try {
+ VersionRange.parse(versionRange)
+ } catch (InvalidVersionException ex) {
+ throw new InvalidInitializrMetadataException("Invalid version range '$versionRange' for " +
+ "dependency with id '$id'")
+ }
+ }
+ }
+
+ /**
+ * 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()
+ }
+
+}
diff --git a/initializr/src/main/groovy/io/spring/initializr/metadata/DependencyGroup.groovy b/initializr/src/main/groovy/io/spring/initializr/metadata/DependencyGroup.groovy
new file mode 100644
index 00000000..8537f888
--- /dev/null
+++ b/initializr/src/main/groovy/io/spring/initializr/metadata/DependencyGroup.groovy
@@ -0,0 +1,31 @@
+/*
+ * 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
+
+/**
+ * A group of {@link Dependency} instances identified by a name.
+ *
+ * @author Stephane Nicoll
+ * @since 1.0
+ */
+class DependencyGroup {
+
+ String name
+
+ final List content = []
+
+}
diff --git a/initializr/src/main/groovy/io/spring/initializr/metadata/InitializrMetadata.groovy b/initializr/src/main/groovy/io/spring/initializr/metadata/InitializrMetadata.groovy
new file mode 100644
index 00000000..a192aa28
--- /dev/null
+++ b/initializr/src/main/groovy/io/spring/initializr/metadata/InitializrMetadata.groovy
@@ -0,0 +1,130 @@
+/*
+ * 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.InitializrConfiguration
+
+/**
+ * Meta-data used to generate a project.
+ *
+ * @author Stephane Nicoll
+ * @since 1.0
+ * @see ServiceCapability
+ */
+class InitializrMetadata {
+
+ final InitializrConfiguration configuration
+
+ final DependenciesCapability dependencies = new DependenciesCapability()
+
+ final TypeCapability types = new TypeCapability()
+
+ final SingleSelectCapability bootVersions = new SingleSelectCapability('bootVersion')
+
+ final SingleSelectCapability packagings = new SingleSelectCapability('packaging')
+
+ final SingleSelectCapability javaVersions = new SingleSelectCapability('javaVersion')
+
+ final SingleSelectCapability languages = new SingleSelectCapability('language')
+
+ final TextCapability name = new TextCapability('name', 'demo')
+
+ final TextCapability description = new TextCapability('description', 'Demo project for Spring Boot')
+
+ final TextCapability groupId = new TextCapability('groupId', 'org.test')
+
+ final TextCapability artifactId = new ArtifactIdCapability(name)
+
+ final TextCapability version = new TextCapability('version', '0.0.1-SNAPSHOT')
+
+ final TextCapability packageName = new PackageCapability(name)
+
+ InitializrMetadata(InitializrConfiguration configuration) {
+ this.configuration = configuration
+ }
+
+ /**
+ * Validate the meta-data.
+ */
+ void validate() {
+ dependencies.validate()
+ }
+
+ /**
+ * 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"
+ }
+
+ /**
+ * 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')
+ 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')
+ this.nameCapability = nameCapability
+ }
+
+ @Override
+ String getContent() {
+ String value = super.getContent()
+ value == null ? nameCapability.content.replace('-', '.') : value
+ }
+ }
+
+}
diff --git a/initializr/src/main/groovy/io/spring/initializr/metadata/InitializrMetadataBuilder.groovy b/initializr/src/main/groovy/io/spring/initializr/metadata/InitializrMetadataBuilder.groovy
new file mode 100644
index 00000000..2a7de551
--- /dev/null
+++ b/initializr/src/main/groovy/io/spring/initializr/metadata/InitializrMetadataBuilder.groovy
@@ -0,0 +1,98 @@
+/*
+ * 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.InitializrConfiguration
+
+/**
+ * Builder for {@link InitializrMetadata}.
+ *
+ * @author Stephane Nicoll
+ * @since 1.0
+ * @see InitializrMetadataCustomizer
+ */
+class InitializrMetadataBuilder {
+
+ private final List customizers = []
+ private InitializrConfiguration configuration
+
+ /**
+ * Adds the specified configuration.
+ * @see InitializrProperties
+ */
+ InitializrMetadataBuilder fromConfiguration(InitializrProperties configuration) {
+ this.configuration = configuration
+ withCustomizer(new InitializerPropertiesCustomizer(configuration))
+ }
+
+ /**
+ * Adds a {@link InitializrMetadataCustomizer}. customizers are invoked in their
+ * order of addition.
+ * @see InitializrMetadataCustomizer
+ */
+ InitializrMetadataBuilder withCustomizer(InitializrMetadataCustomizer customizer) {
+ customizers << customizer
+ this
+ }
+
+ /**
+ * Build a {@link InitializrMetadata} baed on the state of this builder.
+ */
+ InitializrMetadata build() {
+ InitializrConfiguration config = this.configuration ?: new InitializrConfiguration()
+ InitializrMetadata instance = createInstance(config)
+ for (InitializrMetadataCustomizer customizer : customizers) {
+ customizer.customize(instance)
+ }
+ instance.validate()
+ instance
+ }
+
+ /**
+ * Creates an empty instance based on the specified {@link InitializrConfiguration}
+ */
+ protected InitializrMetadata createInstance(InitializrConfiguration configuration) {
+ new InitializrMetadata(configuration)
+ }
+
+ static class InitializerPropertiesCustomizer implements InitializrMetadataCustomizer {
+
+ private final InitializrProperties properties
+
+ InitializerPropertiesCustomizer(InitializrProperties properties) {
+ this.properties = properties
+ }
+
+ @Override
+ void customize(InitializrMetadata metadata) { // NICE: merge
+ metadata.dependencies.content.addAll(properties.dependencies)
+ metadata.types.content.addAll(properties.types)
+ metadata.bootVersions.content.addAll(properties.bootVersions)
+ metadata.packagings.content.addAll(properties.packagings)
+ metadata.javaVersions.content.addAll(properties.javaVersions)
+ metadata.languages.content.addAll(properties.languages)
+ metadata.groupId.content = properties.defaults.groupId
+ metadata.artifactId.content = properties.defaults.artifactId
+ metadata.version.content = properties.defaults.version
+ metadata.name.content = properties.defaults.name
+ metadata.description.content = properties.defaults.description
+ metadata.packageName.content = properties.defaults.packageName
+ }
+ }
+
+
+}
diff --git a/initializr/src/main/groovy/io/spring/initializr/InitializrMetadataCustomizer.groovy b/initializr/src/main/groovy/io/spring/initializr/metadata/InitializrMetadataCustomizer.groovy
similarity index 69%
rename from initializr/src/main/groovy/io/spring/initializr/InitializrMetadataCustomizer.groovy
rename to initializr/src/main/groovy/io/spring/initializr/metadata/InitializrMetadataCustomizer.groovy
index e6aaadfe..d4cb142b 100644
--- a/initializr/src/main/groovy/io/spring/initializr/InitializrMetadataCustomizer.groovy
+++ b/initializr/src/main/groovy/io/spring/initializr/metadata/InitializrMetadataCustomizer.groovy
@@ -1,5 +1,5 @@
/*
- * Copyright 2014-2015 the original author or authors.
+ * 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.
@@ -14,12 +14,20 @@
* limitations under the License.
*/
-package io.spring.initializr
+package io.spring.initializr.metadata
/**
- * @author Dave Syer
+ * Strategy interface used to customize the {@link InitializrMetadata}.
*
+ * @author Dave Syer
+ * @since 1.0
*/
interface InitializrMetadataCustomizer {
+
+ /**
+ * Customize the {@link InitializrMetadata}, updating or moving around
+ * capabilities before they are validated.
+ */
void customize(InitializrMetadata metadata)
+
}
diff --git a/initializr/src/main/groovy/io/spring/initializr/InitializrMetadataProvider.groovy b/initializr/src/main/groovy/io/spring/initializr/metadata/InitializrMetadataProvider.groovy
similarity index 90%
rename from initializr/src/main/groovy/io/spring/initializr/InitializrMetadataProvider.groovy
rename to initializr/src/main/groovy/io/spring/initializr/metadata/InitializrMetadataProvider.groovy
index 2e4da27a..b0bfb2af 100644
--- a/initializr/src/main/groovy/io/spring/initializr/InitializrMetadataProvider.groovy
+++ b/initializr/src/main/groovy/io/spring/initializr/metadata/InitializrMetadataProvider.groovy
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2014 the original author or authors.
+ * 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.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package io.spring.initializr
+package io.spring.initializr.metadata
/**
* Provide the {@link InitializrMetadata} to use.
diff --git a/initializr/src/main/groovy/io/spring/initializr/metadata/InitializrProperties.groovy b/initializr/src/main/groovy/io/spring/initializr/metadata/InitializrProperties.groovy
new file mode 100644
index 00000000..a6cc6edc
--- /dev/null
+++ b/initializr/src/main/groovy/io/spring/initializr/metadata/InitializrProperties.groovy
@@ -0,0 +1,57 @@
+/*
+ * 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.InitializrConfiguration
+
+import org.springframework.boot.context.properties.ConfigurationProperties
+
+/**
+ * Configuration of the initializr service.
+ *
+ * @author Stephane Nicoll
+ * @since 1.0
+ */
+@ConfigurationProperties(prefix = 'initializr', ignoreUnknownFields = false)
+class InitializrProperties extends InitializrConfiguration {
+
+ final List dependencies = []
+
+ final List types = []
+
+ final List packagings = []
+
+ final List javaVersions = []
+
+ final List languages = []
+
+ final List bootVersions = []
+
+ final Defaults defaults = new Defaults()
+
+ static class Defaults {
+
+ String groupId = 'org.test'
+ String artifactId
+ String version = '0.0.1-SNAPSHOT'
+ String name = 'demo'
+ String description = 'Demo project for Spring Boot'
+ String packageName
+
+ }
+
+}
diff --git a/initializr/src/main/groovy/io/spring/initializr/InvalidInitializrMetadataException.groovy b/initializr/src/main/groovy/io/spring/initializr/metadata/InvalidInitializrMetadataException.groovy
similarity index 85%
rename from initializr/src/main/groovy/io/spring/initializr/InvalidInitializrMetadataException.groovy
rename to initializr/src/main/groovy/io/spring/initializr/metadata/InvalidInitializrMetadataException.groovy
index ca5b6b11..e6ae863a 100644
--- a/initializr/src/main/groovy/io/spring/initializr/InvalidInitializrMetadataException.groovy
+++ b/initializr/src/main/groovy/io/spring/initializr/metadata/InvalidInitializrMetadataException.groovy
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2014 the original author or authors.
+ * 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.
@@ -14,9 +14,10 @@
* limitations under the License.
*/
-package io.spring.initializr
+package io.spring.initializr.metadata
import groovy.transform.InheritConstructors
+import io.spring.initializr.InitializrException
/**
* Thrown when the configuration defines invalid metadata.
diff --git a/initializr/src/main/groovy/io/spring/initializr/metadata/MetadataElement.groovy b/initializr/src/main/groovy/io/spring/initializr/metadata/MetadataElement.groovy
new file mode 100644
index 00000000..e80c4365
--- /dev/null
+++ b/initializr/src/main/groovy/io/spring/initializr/metadata/MetadataElement.groovy
@@ -0,0 +1,40 @@
+/*
+ * 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
+
+/**
+ * A basic meta-data element
+ *
+ * @author Stephane Nicoll
+ * @since 1.0
+ */
+class MetadataElement {
+
+ /**
+ * A visual representation of this element.
+ */
+ String name
+
+ /**
+ * The unique id of this element for a given capability.
+ */
+ String id
+
+ String getName() {
+ (name ?: id)
+ }
+}
\ No newline at end of file
diff --git a/initializr/src/main/groovy/io/spring/initializr/metadata/ServiceCapability.groovy b/initializr/src/main/groovy/io/spring/initializr/metadata/ServiceCapability.groovy
new file mode 100644
index 00000000..e8dda105
--- /dev/null
+++ b/initializr/src/main/groovy/io/spring/initializr/metadata/ServiceCapability.groovy
@@ -0,0 +1,46 @@
+/*
+ * 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
+
+/**
+ * Defines a capability of the initializr service. Each capability
+ * is defined by a id and a {@link ServiceCapabilityType type}.
+ *
+ * @author Stephane Nicoll
+ * @since 1.0
+ */
+abstract class ServiceCapability {
+
+ final String id
+
+ final ServiceCapabilityType type
+
+ String description
+
+ protected ServiceCapability(String id, ServiceCapabilityType type) {
+ this.id = id
+ this.type = type
+ }
+
+ /**
+ * Return the "content" of this capability. The structure of the content
+ * vastly depends on the {@link ServiceCapability type} of the capability.
+ */
+ abstract T getContent()
+
+}
+
diff --git a/initializr/src/main/groovy/io/spring/initializr/metadata/ServiceCapabilityType.groovy b/initializr/src/main/groovy/io/spring/initializr/metadata/ServiceCapabilityType.groovy
new file mode 100644
index 00000000..c0fe83ef
--- /dev/null
+++ b/initializr/src/main/groovy/io/spring/initializr/metadata/ServiceCapabilityType.groovy
@@ -0,0 +1,54 @@
+/*
+ * 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
+
+/**
+ * Defines the supported service capability type.
+ *
+ * @author Stephane Nicoll
+ * @since 1.0
+ */
+enum ServiceCapabilityType {
+
+ /**
+ * A special type that defines the action to use.
+ */
+ ACTION('action'),
+
+ /**
+ * A simple text value with no option.
+ */
+ TEXT('text'),
+
+ /**
+ * A simple value to be chosen amongst the specified options.
+ */
+ 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')
+
+ final String name
+
+ ServiceCapabilityType(String name) {
+ this.name = name
+ }
+
+}
diff --git a/initializr/src/main/groovy/io/spring/initializr/metadata/SingleSelectCapability.groovy b/initializr/src/main/groovy/io/spring/initializr/metadata/SingleSelectCapability.groovy
new file mode 100644
index 00000000..37ffb5c0
--- /dev/null
+++ b/initializr/src/main/groovy/io/spring/initializr/metadata/SingleSelectCapability.groovy
@@ -0,0 +1,40 @@
+/*
+ * 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
+
+/**
+ * A {@link ServiceCapabilityType#SINGLE_SELECT single select} capability.
+ *
+ * @author Stephane Nicoll
+ * @since 1.0
+ */
+class SingleSelectCapability extends ServiceCapability> {
+
+ final List content = []
+
+ SingleSelectCapability(String id) {
+ super(id, ServiceCapabilityType.SINGLE_SELECT)
+ }
+
+ /**
+ * Return the default element of this capability.
+ */
+ DefaultMetadataElement getDefault() {
+ return content.find { it.default }
+ }
+
+}
diff --git a/initializr/src/main/groovy/io/spring/initializr/metadata/TextCapability.groovy b/initializr/src/main/groovy/io/spring/initializr/metadata/TextCapability.groovy
new file mode 100644
index 00000000..7a96ee07
--- /dev/null
+++ b/initializr/src/main/groovy/io/spring/initializr/metadata/TextCapability.groovy
@@ -0,0 +1,39 @@
+/*
+ * 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
+
+/**
+ * A {@link ServiceCapabilityType#TEXT text} capability.
+ *
+ * @author Stephane Nicoll
+ * @since 1.0
+ */
+class TextCapability extends ServiceCapability {
+
+ String content
+
+ TextCapability(String id) {
+ super(id, ServiceCapabilityType.TEXT);
+ }
+
+ TextCapability(String id, String content) {
+ this(id)
+ this.content = content
+ }
+
+}
+
diff --git a/initializr/src/main/groovy/io/spring/initializr/metadata/Type.groovy b/initializr/src/main/groovy/io/spring/initializr/metadata/Type.groovy
new file mode 100644
index 00000000..564011c1
--- /dev/null
+++ b/initializr/src/main/groovy/io/spring/initializr/metadata/Type.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
+
+/**
+ * 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
+ * @since 1.0
+ */
+class Type extends DefaultMetadataElement {
+
+ 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/src/main/groovy/io/spring/initializr/metadata/TypeCapability.groovy b/initializr/src/main/groovy/io/spring/initializr/metadata/TypeCapability.groovy
new file mode 100644
index 00000000..e8dadf80
--- /dev/null
+++ b/initializr/src/main/groovy/io/spring/initializr/metadata/TypeCapability.groovy
@@ -0,0 +1,48 @@
+/*
+ * 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
+
+/**
+ * An {@link ServiceCapabilityType#ACTION action} capability.
+ *
+ * @author Stephane Nicoll
+ * @since 1.0
+ */
+class TypeCapability extends ServiceCapability> {
+
+ final List content = []
+
+ TypeCapability() {
+ super('type', ServiceCapabilityType.ACTION)
+ }
+
+ /**
+ * 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) }
+ }
+
+ /**
+ * Return the default {@link Type}.
+ */
+ Type getDefault() {
+ return content.find { it.default }
+ }
+
+}
diff --git a/initializr/src/main/groovy/io/spring/initializr/DefaultInitializrMetadataProvider.groovy b/initializr/src/main/groovy/io/spring/initializr/support/DefaultInitializrMetadataProvider.groovy
similarity index 73%
rename from initializr/src/main/groovy/io/spring/initializr/DefaultInitializrMetadataProvider.groovy
rename to initializr/src/main/groovy/io/spring/initializr/support/DefaultInitializrMetadataProvider.groovy
index 6f1bf01f..b8363eed 100644
--- a/initializr/src/main/groovy/io/spring/initializr/DefaultInitializrMetadataProvider.groovy
+++ b/initializr/src/main/groovy/io/spring/initializr/support/DefaultInitializrMetadataProvider.groovy
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2014 the original author or authors.
+ * 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.
@@ -14,9 +14,12 @@
* limitations under the License.
*/
-package io.spring.initializr
+package io.spring.initializr.support
import groovy.util.logging.Slf4j
+import io.spring.initializr.metadata.DefaultMetadataElement
+import io.spring.initializr.metadata.InitializrMetadata
+import io.spring.initializr.metadata.InitializrMetadataProvider
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.cache.annotation.Cacheable
@@ -43,17 +46,18 @@ class DefaultInitializrMetadataProvider implements InitializrMetadataProvider {
InitializrMetadata get() {
def bootVersions = fetchBootVersions()
if (bootVersions) {
- metadata.merge(bootVersions)
+ metadata.bootVersions.content.clear()
+ metadata.bootVersions.content.addAll(bootVersions)
}
metadata
}
- protected List fetchBootVersions() {
- def url = metadata.env.springBootMetadataUrl
+ protected List fetchBootVersions() {
+ def url = metadata.configuration.env.springBootMetadataUrl
if (url) {
try {
log.info("Fetching boot metadata from $url")
- return new SpringBootMetadataReader(url).getBootVersions()
+ return new SpringBootMetadataReader(url).bootVersions
} catch (Exception e) {
log.warn('Failed to fetch spring boot metadata', e)
}
diff --git a/initializr/src/main/groovy/io/spring/initializr/SpringBootMetadataReader.groovy b/initializr/src/main/groovy/io/spring/initializr/support/SpringBootMetadataReader.groovy
similarity index 85%
rename from initializr/src/main/groovy/io/spring/initializr/SpringBootMetadataReader.groovy
rename to initializr/src/main/groovy/io/spring/initializr/support/SpringBootMetadataReader.groovy
index b5e46302..8f3a3466 100644
--- a/initializr/src/main/groovy/io/spring/initializr/SpringBootMetadataReader.groovy
+++ b/initializr/src/main/groovy/io/spring/initializr/support/SpringBootMetadataReader.groovy
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2014 the original author or authors.
+ * 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.
@@ -14,9 +14,10 @@
* limitations under the License.
*/
-package io.spring.initializr
+package io.spring.initializr.support
import groovy.json.JsonSlurper
+import io.spring.initializr.metadata.DefaultMetadataElement
import org.springframework.web.client.RestTemplate
@@ -44,9 +45,9 @@ class SpringBootMetadataReader {
/**
* Return the boot versions parsed by this instance.
*/
- List getBootVersions() {
+ List getBootVersions() {
content.projectReleases.collect {
- def version = new InitializrMetadata.BootVersion()
+ def version = new DefaultMetadataElement()
version.id = it.version
def name = it.versionDisplayName
version.name = (it.snapshot ? name + ' (SNAPSHOT)' : name)
diff --git a/initializr/src/main/groovy/io/spring/initializr/support/GroovyTemplate.groovy b/initializr/src/main/groovy/io/spring/initializr/util/GroovyTemplate.groovy
similarity index 95%
rename from initializr/src/main/groovy/io/spring/initializr/support/GroovyTemplate.groovy
rename to initializr/src/main/groovy/io/spring/initializr/util/GroovyTemplate.groovy
index 1e5b941f..d54271e3 100644
--- a/initializr/src/main/groovy/io/spring/initializr/support/GroovyTemplate.groovy
+++ b/initializr/src/main/groovy/io/spring/initializr/util/GroovyTemplate.groovy
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2014 the original author or authors.
+ * 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.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package io.spring.initializr.support
+package io.spring.initializr.util
import groovy.text.GStringTemplateEngine
import groovy.text.Template
diff --git a/initializr/src/main/groovy/io/spring/initializr/support/InvalidVersionException.groovy b/initializr/src/main/groovy/io/spring/initializr/util/InvalidVersionException.groovy
similarity index 95%
rename from initializr/src/main/groovy/io/spring/initializr/support/InvalidVersionException.groovy
rename to initializr/src/main/groovy/io/spring/initializr/util/InvalidVersionException.groovy
index 8ec74daa..1d5b174e 100644
--- a/initializr/src/main/groovy/io/spring/initializr/support/InvalidVersionException.groovy
+++ b/initializr/src/main/groovy/io/spring/initializr/util/InvalidVersionException.groovy
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package io.spring.initializr.support
+package io.spring.initializr.util
import groovy.transform.InheritConstructors
diff --git a/initializr/src/main/groovy/io/spring/initializr/support/Version.groovy b/initializr/src/main/groovy/io/spring/initializr/util/Version.groovy
similarity index 99%
rename from initializr/src/main/groovy/io/spring/initializr/support/Version.groovy
rename to initializr/src/main/groovy/io/spring/initializr/util/Version.groovy
index 83b7c80a..58515bb2 100644
--- a/initializr/src/main/groovy/io/spring/initializr/support/Version.groovy
+++ b/initializr/src/main/groovy/io/spring/initializr/util/Version.groovy
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package io.spring.initializr.support
+package io.spring.initializr.util
import groovy.transform.EqualsAndHashCode
import groovy.transform.ToString
diff --git a/initializr/src/main/groovy/io/spring/initializr/support/VersionRange.groovy b/initializr/src/main/groovy/io/spring/initializr/util/VersionRange.groovy
similarity index 98%
rename from initializr/src/main/groovy/io/spring/initializr/support/VersionRange.groovy
rename to initializr/src/main/groovy/io/spring/initializr/util/VersionRange.groovy
index a5e6c6ea..2f05d2da 100644
--- a/initializr/src/main/groovy/io/spring/initializr/support/VersionRange.groovy
+++ b/initializr/src/main/groovy/io/spring/initializr/util/VersionRange.groovy
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package io.spring.initializr.support
+package io.spring.initializr.util
import groovy.transform.EqualsAndHashCode
import groovy.transform.ToString
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 07dcecf9..7467c10d 100644
--- a/initializr/src/main/groovy/io/spring/initializr/web/AbstractInitializrController.groovy
+++ b/initializr/src/main/groovy/io/spring/initializr/web/AbstractInitializrController.groovy
@@ -18,12 +18,12 @@ package io.spring.initializr.web
import javax.annotation.PostConstruct
-import io.spring.initializr.InitializrMetadataProvider
+import io.spring.initializr.metadata.InitializrMetadataProvider
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.web.servlet.support.ServletUriComponentsBuilder
-import static io.spring.initializr.support.GroovyTemplate.template
+import static io.spring.initializr.util.GroovyTemplate.template
/**
* A base controller that uses a {@link InitializrMetadataProvider}
@@ -40,7 +40,7 @@ abstract class AbstractInitializrController {
@PostConstruct
void initialize() {
- forceSsl = metadataProvider.get().env.forceSsl
+ forceSsl = metadataProvider.get().configuration.env.forceSsl
}
/**
@@ -55,7 +55,7 @@ abstract class AbstractInitializrController {
/**
* Generate a full URL of the service, mostly for use in templates.
- * @see io.spring.initializr.InitializrMetadata.Env#forceSsl
+ * @see io.spring.initializr.InitializrConfiguration.Env#forceSsl
*/
protected String generateAppUrl() {
def builder = ServletUriComponentsBuilder.fromCurrentServletMapping()
diff --git a/initializr/src/main/groovy/io/spring/initializr/web/MainController.groovy b/initializr/src/main/groovy/io/spring/initializr/web/MainController.groovy
index 1b9ea7c9..e1c835fa 100644
--- a/initializr/src/main/groovy/io/spring/initializr/web/MainController.groovy
+++ b/initializr/src/main/groovy/io/spring/initializr/web/MainController.groovy
@@ -17,10 +17,13 @@
package io.spring.initializr.web
import groovy.util.logging.Slf4j
-import io.spring.initializr.CommandLineHelpGenerator
-import io.spring.initializr.InitializrMetadataVersion
-import io.spring.initializr.ProjectGenerator
-import io.spring.initializr.ProjectRequest
+import io.spring.initializr.generator.CommandLineHelpGenerator
+import io.spring.initializr.mapper.InitializrMetadataJsonMapper
+import io.spring.initializr.mapper.InitializrMetadataV21JsonMapper
+import io.spring.initializr.mapper.InitializrMetadataV2JsonMapper
+import io.spring.initializr.mapper.InitializrMetadataVersion
+import io.spring.initializr.generator.ProjectGenerator
+import io.spring.initializr.generator.ProjectRequest
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.http.HttpHeaders
@@ -55,7 +58,7 @@ class MainController extends AbstractInitializrController {
@ModelAttribute
ProjectRequest projectRequest() {
def request = new ProjectRequest()
- metadataProvider.get().initializeProjectRequest(request)
+ request.initialize(metadataProvider.get())
request
}
@@ -92,10 +95,17 @@ class MainController extends AbstractInitializrController {
private ResponseEntity serviceCapabilitiesFor(InitializrMetadataVersion version) {
String appUrl = generateAppUrl()
- def content = metadataProvider.get().generateJson(version, appUrl)
+ def content = getJsonMapper(version).write(metadataProvider.get(), appUrl)
return ResponseEntity.ok().contentType(version.mediaType).body(content)
}
+ private static InitializrMetadataJsonMapper getJsonMapper(InitializrMetadataVersion version) {
+ switch(version) {
+ case InitializrMetadataVersion.V2: return new InitializrMetadataV2JsonMapper();
+ default: return new InitializrMetadataV21JsonMapper();
+ }
+ }
+
@RequestMapping(value = '/', produces = 'text/html')
@ResponseBody
String home() {
diff --git a/initializr/src/main/resources/META-INF/spring.factories b/initializr/src/main/resources/META-INF/spring.factories
index 8726d25e..a6629e17 100644
--- a/initializr/src/main/resources/META-INF/spring.factories
+++ b/initializr/src/main/resources/META-INF/spring.factories
@@ -1 +1 @@
-org.springframework.boot.autoconfigure.EnableAutoConfiguration=io.spring.initializr.InitializrAutoConfiguration
\ No newline at end of file
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=io.spring.initializr.config.InitializrAutoConfiguration
\ No newline at end of file
diff --git a/initializr/src/main/resources/templates/home.html b/initializr/src/main/resources/templates/home.html
index 2515795e..52ed94bc 100644
--- a/initializr/src/main/resources/templates/home.html
+++ b/initializr/src/main/resources/templates/home.html
@@ -26,45 +26,45 @@