org.seleniumhq.selenium
selenium-firefox-driver
@@ -143,10 +138,6 @@
-
- org.codehaus.gmavenplus
- gmavenplus-plugin
-
diff --git a/initializr-web/src/main/groovy/io/spring/initializr/web/autoconfigure/InitializrAutoConfiguration.groovy b/initializr-web/src/main/groovy/io/spring/initializr/web/autoconfigure/InitializrAutoConfiguration.groovy
deleted file mode 100644
index 624c431d..00000000
--- a/initializr-web/src/main/groovy/io/spring/initializr/web/autoconfigure/InitializrAutoConfiguration.groovy
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Copyright 2012-2017 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.spring.initializr.web.autoconfigure
-
-import org.springframework.web.servlet.resource.ResourceUrlProvider
-
-import java.util.concurrent.TimeUnit
-
-import com.github.benmanes.caffeine.cache.Caffeine
-import io.spring.initializr.generator.ProjectGenerator
-import io.spring.initializr.generator.ProjectRequestPostProcessor
-import io.spring.initializr.generator.ProjectRequestResolver
-import io.spring.initializr.generator.ProjectResourceLocator
-import io.spring.initializr.metadata.DependencyMetadataProvider
-import io.spring.initializr.metadata.InitializrMetadataBuilder
-import io.spring.initializr.metadata.InitializrMetadataProvider
-import io.spring.initializr.metadata.InitializrProperties
-import io.spring.initializr.util.GroovyTemplate
-import io.spring.initializr.web.project.MainController
-import io.spring.initializr.web.support.DefaultDependencyMetadataProvider
-import io.spring.initializr.web.support.DefaultInitializrMetadataProvider
-import io.spring.initializr.web.ui.UiController
-
-import org.springframework.beans.factory.annotation.Autowired
-import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
-import org.springframework.boot.bind.RelaxedPropertyResolver
-import org.springframework.boot.context.properties.EnableConfigurationProperties
-import org.springframework.cache.Cache
-import org.springframework.cache.CacheManager
-import org.springframework.cache.annotation.EnableCaching
-import org.springframework.cache.caffeine.CaffeineCache
-import org.springframework.cache.concurrent.ConcurrentMapCache
-import org.springframework.cache.support.SimpleCacheManager
-import org.springframework.context.annotation.Bean
-import org.springframework.context.annotation.Configuration
-import org.springframework.core.env.Environment
-import org.springframework.web.client.RestTemplate
-
-/**
- * {@link org.springframework.boot.autoconfigure.EnableAutoConfiguration
- * Auto-configuration} to configure Spring initializr. In a web environment,
- * configures the necessary controller to serve the applications from the
- * root context.
- *
- * Project generation can be customized by defining a custom
- * {@link ProjectGenerator}.
- *
- * @author Stephane Nicoll
- */
-@Configuration
-@EnableCaching
-@EnableConfigurationProperties(InitializrProperties)
-class InitializrAutoConfiguration {
-
- @Autowired(required = false)
- List postProcessors = []
-
- @Bean
- WebConfig webConfig() {
- new WebConfig()
- }
-
- @Bean
- @ConditionalOnMissingBean
- MainController initializrMainController(InitializrMetadataProvider metadataProvider,
- GroovyTemplate groovyTemplate,
- ResourceUrlProvider resourceUrlProvider,
- ProjectGenerator projectGenerator,
- DependencyMetadataProvider dependencyMetadataProvider) {
- new MainController(metadataProvider, groovyTemplate, resourceUrlProvider
- , projectGenerator, dependencyMetadataProvider)
- }
-
- @Bean
- @ConditionalOnMissingBean
- UiController initializrUiController() {
- new UiController()
- }
-
- @Bean
- @ConditionalOnMissingBean
- ProjectGenerator projectGenerator() {
- new ProjectGenerator()
- }
-
- @Bean
- @ConditionalOnMissingBean
- GroovyTemplate groovyTemplate(Environment environment) {
- def resolver = new RelaxedPropertyResolver(environment, 'spring.groovy.template.')
- boolean cache = resolver.getProperty('cache', Boolean.class, true)
- def groovyTemplate = new GroovyTemplate()
- groovyTemplate.cache = cache
- groovyTemplate
- }
-
- @Bean
- @ConditionalOnMissingBean
- ProjectRequestResolver projectRequestResolver() {
- new ProjectRequestResolver(postProcessors)
- }
-
- @Bean
- ProjectResourceLocator projectResourceLocator() {
- return new ProjectResourceLocator()
- }
-
- @Bean
- @ConditionalOnMissingBean(InitializrMetadataProvider)
- InitializrMetadataProvider initializrMetadataProvider(InitializrProperties properties) {
- def metadata = InitializrMetadataBuilder.fromInitializrProperties(properties).build()
- new DefaultInitializrMetadataProvider(metadata, new RestTemplate())
- }
-
- @Bean
- @ConditionalOnMissingBean
- DependencyMetadataProvider dependencyMetadataProvider() {
- new DefaultDependencyMetadataProvider()
- }
-
- @Bean
- @ConditionalOnMissingBean
- CacheManager cacheManager() {
- def cacheManager = new SimpleCacheManager()
- cacheManager.caches = Arrays.asList(
- createConcurrentMapCache(600, 'initializr'),
- new ConcurrentMapCache('dependency-metadata'),
- new ConcurrentMapCache("project-resources"))
- cacheManager
- }
-
- private static Cache createConcurrentMapCache(Long timeToLive, String name) {
- new CaffeineCache(name, Caffeine
- .newBuilder()
- .expireAfterWrite(timeToLive, TimeUnit.SECONDS)
- .build())
- }
-
-}
diff --git a/initializr-web/src/main/groovy/io/spring/initializr/web/mapper/DependencyMetadataV21JsonMapper.groovy b/initializr-web/src/main/groovy/io/spring/initializr/web/mapper/DependencyMetadataV21JsonMapper.groovy
deleted file mode 100644
index afc0b09d..00000000
--- a/initializr-web/src/main/groovy/io/spring/initializr/web/mapper/DependencyMetadataV21JsonMapper.groovy
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright 2012-2017 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.spring.initializr.web.mapper
-
-import groovy.json.JsonBuilder
-import io.spring.initializr.metadata.BillOfMaterials
-import io.spring.initializr.metadata.Dependency
-import io.spring.initializr.metadata.DependencyMetadata
-import io.spring.initializr.metadata.Repository
-
-/**
- * A {@link DependencyMetadataJsonMapper} handling the metadata format for v2.1.
- *
- * @author Stephane Nicoll
- */
-class DependencyMetadataV21JsonMapper implements DependencyMetadataJsonMapper {
-
- @Override
- String write(DependencyMetadata metadata) {
- JsonBuilder json = new JsonBuilder()
- json {
- bootVersion metadata.bootVersion.toString()
- dependencies metadata.dependencies.collectEntries { id, d ->
- [id, mapDependency(d)]
- }
- repositories metadata.repositories.collectEntries { id, r -> [id, mapRepository(r)] }
- boms metadata.boms.collectEntries { id, b -> [id, mapBom(b)] }
- }
- json.toString()
- }
-
- private static mapDependency(Dependency dep) {
- def result = [:]
- result.groupId = dep.groupId
- result.artifactId = dep.artifactId
- if (dep.version) {
- result.version = dep.version
- }
- result.scope = dep.scope
- if (dep.bom) {
- result.bom = dep.bom
- }
- if (dep.repository) {
- result.repository = dep.repository
- }
- result
- }
-
- private static mapRepository(Repository repo) {
- def result = [:]
- result.name = repo.name
- result.url = repo.url
- result.snapshotEnabled = repo.snapshotsEnabled
- result
- }
-
- private static mapBom(BillOfMaterials bom) {
- def result = [:]
- result.groupId = bom.groupId
- result.artifactId = bom.artifactId
- if (bom.version) {
- result.version = bom.version
- }
- if (bom.repositories) {
- result.repositories = bom.repositories
- }
- result
- }
-
-}
diff --git a/initializr-web/src/main/groovy/io/spring/initializr/web/mapper/InitializrMetadataV21JsonMapper.groovy b/initializr-web/src/main/groovy/io/spring/initializr/web/mapper/InitializrMetadataV21JsonMapper.groovy
deleted file mode 100644
index fa40d9b8..00000000
--- a/initializr-web/src/main/groovy/io/spring/initializr/web/mapper/InitializrMetadataV21JsonMapper.groovy
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright 2012-2017 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.spring.initializr.web.mapper
-
-import org.springframework.hateoas.TemplateVariable
-import org.springframework.hateoas.TemplateVariables
-import org.springframework.hateoas.UriTemplate
-
-/**
- * A {@link InitializrMetadataJsonMapper} handling the metadata format for v2.1
- *
- * Version 2.1 brings the 'versionRange' attribute for a dependency to restrict
- * the Spring Boot versions that can be used against it. That version also adds
- * an additional `dependencies` endpoint.
- *
- * @author Stephane Nicoll
- */
-class InitializrMetadataV21JsonMapper extends InitializrMetadataV2JsonMapper {
-
- private final TemplateVariables dependenciesVariables
-
- InitializrMetadataV21JsonMapper() {
- this.dependenciesVariables = new TemplateVariables(
- new TemplateVariable('bootVersion', TemplateVariable.VariableType.REQUEST_PARAM)
- )
- }
-
- @Override
- protected links(parent, types, appUrl) {
- def links = super.links(parent, types, appUrl)
- links['dependencies'] = dependenciesLink(appUrl)
- links
- }
-
- @Override
- protected mapDependency(dependency) {
- def content = mapValue(dependency)
- if (dependency.versionRange) {
- content['versionRange'] = dependency.versionRange
- }
- if (dependency.links) {
- content._links = LinkMapper.mapLinks(dependency.links)
- }
- content
- }
-
- private dependenciesLink(appUrl) {
- String uri = appUrl != null ? appUrl + '/dependencies' : '/dependencies'
- UriTemplate uriTemplate = new UriTemplate(uri, this.dependenciesVariables)
- def result = [:]
- result.href = uriTemplate.toString()
- result.templated = true
- result
- }
-}
diff --git a/initializr-web/src/main/groovy/io/spring/initializr/web/mapper/InitializrMetadataV2JsonMapper.groovy b/initializr-web/src/main/groovy/io/spring/initializr/web/mapper/InitializrMetadataV2JsonMapper.groovy
deleted file mode 100644
index 8830d03f..00000000
--- a/initializr-web/src/main/groovy/io/spring/initializr/web/mapper/InitializrMetadataV2JsonMapper.groovy
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * Copyright 2012-2017 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.spring.initializr.web.mapper
-
-import groovy.json.JsonBuilder
-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
-
-/**
- * A {@link InitializrMetadataJsonMapper} handling the metadata format for v2.
- *
- * @author Stephane Nicoll
- */
-class InitializrMetadataV2JsonMapper implements InitializrMetadataJsonMapper {
-
- private final TemplateVariables templateVariables
-
- InitializrMetadataV2JsonMapper() {
- this.templateVariables = new TemplateVariables(
- new TemplateVariable('dependencies', TemplateVariable.VariableType.REQUEST_PARAM),
- new TemplateVariable('packaging', TemplateVariable.VariableType.REQUEST_PARAM),
- new TemplateVariable('javaVersion', TemplateVariable.VariableType.REQUEST_PARAM),
- new TemplateVariable('language', TemplateVariable.VariableType.REQUEST_PARAM),
- new TemplateVariable('bootVersion', TemplateVariable.VariableType.REQUEST_PARAM),
- new TemplateVariable('groupId', TemplateVariable.VariableType.REQUEST_PARAM),
- new TemplateVariable('artifactId', TemplateVariable.VariableType.REQUEST_PARAM),
- new TemplateVariable('version', TemplateVariable.VariableType.REQUEST_PARAM),
- new TemplateVariable('name', TemplateVariable.VariableType.REQUEST_PARAM),
- new TemplateVariable('description', TemplateVariable.VariableType.REQUEST_PARAM),
- new TemplateVariable('packageName', TemplateVariable.VariableType.REQUEST_PARAM)
- )
- }
-
- @Override
- String write(InitializrMetadata metadata, String appUrl) {
- JsonBuilder json = new JsonBuilder()
- json {
- links(delegate, metadata.types.content, appUrl)
- dependencies(delegate, metadata.dependencies)
- 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()
- }
-
- protected links(parent, types, appUrl) {
- def content = [:]
- types.each {
- content[it.id] = link(appUrl, it)
- }
- parent._links content
- }
-
- protected link(appUrl, type) {
- def result = [:]
- result.href = generateTemplatedUri(appUrl, type)
- result.templated = true
- result
- }
-
- private generateTemplatedUri(appUrl, type) {
- String uri = appUrl != null ? appUrl + type.action : type.action
- uri += "?type=$type.id"
- UriTemplate uriTemplate = new UriTemplate(uri, this.templateVariables)
- uriTemplate.toString()
- }
-
-
- protected dependencies(parent, capability) {
- parent."$capability.id" {
- type "$capability.type.name"
- values capability.content.collect {
- mapDependencyGroup(it)
- }
- }
- }
-
- protected type(parent, capability) {
- parent.type {
- type 'action'
- def defaultType = capability.default
- if (defaultType) {
- 'default' defaultType.id
- }
- values capability.content.collect {
- mapType(it)
- }
- }
- }
-
- protected singleSelect(parent, SingleSelectCapability capability) {
- parent."$capability.id" {
- type "$capability.type.name"
- def defaultValue = capability.default
- if (defaultValue) {
- 'default' defaultValue.id
- }
- values capability.content.collect {
- mapValue(it)
- }
- }
- }
-
- protected text(parent, capability) {
- parent."$capability.id" {
- type "$capability.type.name"
- def defaultValue = capability.content
- if (defaultValue) {
- 'default' defaultValue
- }
- }
- }
-
- protected mapDependencyGroup(group) {
- def result = [:]
- result.name = group.name
- if (group.hasProperty('description') && group.description) {
- result.description = group.description
- }
- def items = []
- group.content.collect {
- def dependency = mapDependency(it)
- if (dependency) {
- items << dependency
- }
- }
- result.values = items
- result
- }
-
- protected mapDependency(dependency) {
- if (!dependency.versionRange) { // only map the dependency if no versionRange is set
- mapValue(dependency)
- }
- }
-
- protected mapType(type) {
- def result = mapValue(type)
- result.action = type.action
- result.tags = type.tags
- result
- }
-
- protected mapValue(value) {
- def result = [:]
- result.id = value.id
- result.name = value.name
- if (value.hasProperty('description') && value.description) {
- result.description = value.description
- }
- result
- }
-
-}
diff --git a/initializr-web/src/main/groovy/io/spring/initializr/web/mapper/LinkMapper.groovy b/initializr-web/src/main/groovy/io/spring/initializr/web/mapper/LinkMapper.groovy
deleted file mode 100644
index 535690fd..00000000
--- a/initializr-web/src/main/groovy/io/spring/initializr/web/mapper/LinkMapper.groovy
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright 2012-2017 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.spring.initializr.web.mapper
-
-import io.spring.initializr.metadata.Link
-
-/**
- * Generate a json representation for {@link Link}
- *
- * @author Stephane Nicoll
- */
-class LinkMapper {
-
- /**
- * Map the specified links to a json model. If several links share
- * the same relation, they are grouped together.
- * @param links the links to map
- * @return a model for the specified links
- */
- static mapLinks(List links) {
- def result = [:]
- Map> byRel = new LinkedHashMap<>()
- links.each {
- def relLinks = byRel[it.rel]
- if (!relLinks) {
- relLinks = []
- byRel[it.rel] = relLinks
- }
- relLinks.add(it)
- }
- byRel.forEach { rel, l ->
- if (l.size() == 1) {
- def root = [:]
- mapLink(l[0], root)
- result[rel] = root
- } else {
- def root = []
- l.each {
- def model = [:]
- mapLink(it, model)
- root << model
- }
- result[rel] = root
- }
- }
- result
- }
-
- private static mapLink(Link link, def model) {
- model.href = link.href
- if (link.templated) {
- model.templated = true
- }
- if (link.description) {
- model.title = link.description
- }
- }
-
-}
diff --git a/initializr-web/src/main/groovy/io/spring/initializr/web/project/AbstractInitializrController.groovy b/initializr-web/src/main/groovy/io/spring/initializr/web/project/AbstractInitializrController.groovy
deleted file mode 100644
index cc7d4e95..00000000
--- a/initializr-web/src/main/groovy/io/spring/initializr/web/project/AbstractInitializrController.groovy
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright 2012-2017 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.spring.initializr.web.project
-
-import org.springframework.web.servlet.resource.ResourceUrlProvider
-
-import javax.servlet.http.HttpServletResponse
-
-import io.spring.initializr.generator.InvalidProjectRequestException
-import io.spring.initializr.metadata.InitializrMetadataProvider
-import io.spring.initializr.util.GroovyTemplate
-
-import org.springframework.http.HttpStatus
-import org.springframework.web.bind.annotation.ExceptionHandler
-import org.springframework.web.servlet.support.ServletUriComponentsBuilder
-
-/**
- * A base controller that uses a {@link InitializrMetadataProvider}
- *
- * @author Stephane Nicoll
- */
-abstract class AbstractInitializrController {
-
- protected final InitializrMetadataProvider metadataProvider
- private final GroovyTemplate groovyTemplate
- private final Closure linkTo
- private Boolean forceSsl
-
- protected AbstractInitializrController(InitializrMetadataProvider metadataProvider,
- ResourceUrlProvider resourceUrlProvider,
- GroovyTemplate groovyTemplate) {
- this.metadataProvider = metadataProvider
- this.groovyTemplate = groovyTemplate
- this.linkTo = { link -> resourceUrlProvider.getForLookupPath(link)?:link }
- }
-
- boolean isForceSsl() {
- if (this.forceSsl == null) {
- this.forceSsl = metadataProvider.get().configuration.env.forceSsl
- }
- return this.forceSsl;
-
- }
-
- @ExceptionHandler
- public void invalidProjectRequest(HttpServletResponse response, InvalidProjectRequestException ex) {
- response.sendError(HttpStatus.BAD_REQUEST.value(), ex.getMessage());
- }
-
- /**
- * Render the home page with the specified template.
- */
- protected String renderHome(String templatePath) {
- def metadata = metadataProvider.get()
-
- def model = [:]
- model['serviceUrl'] = generateAppUrl()
- metadata.properties.each {
- if (it.key.equals('types')) {
- model['types'] = it.value.clone()
- } else {
- model[it.key] = it.value
- }
- }
-
- // Only keep project type
- model['types'].content.removeAll { t -> !'project'.equals(t.tags['format']) }
-
- // Google analytics support
- model['trackingCode'] = metadata.configuration.env.googleAnalyticsTrackingCode
-
- // Linking to static resources
- model['linkTo'] = this.linkTo
-
- groovyTemplate.process templatePath, model
- }
-
- /**
- * Generate a full URL of the service, mostly for use in templates.
- * @see io.spring.initializr.metadata.InitializrConfiguration.Env#forceSsl
- */
- protected String generateAppUrl() {
- def builder = ServletUriComponentsBuilder.fromCurrentServletMapping()
- if (isForceSsl()) {
- builder.scheme('https')
- }
- builder.build()
- }
-
-}
diff --git a/initializr-web/src/main/groovy/io/spring/initializr/web/project/MainController.groovy b/initializr-web/src/main/groovy/io/spring/initializr/web/project/MainController.groovy
deleted file mode 100644
index 5cac19a5..00000000
--- a/initializr-web/src/main/groovy/io/spring/initializr/web/project/MainController.groovy
+++ /dev/null
@@ -1,278 +0,0 @@
-/*
- * Copyright 2012-2017 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.spring.initializr.web.project
-
-import org.springframework.web.servlet.resource.ResourceUrlProvider
-
-import java.nio.charset.StandardCharsets
-import java.util.concurrent.TimeUnit
-
-import groovy.util.logging.Slf4j
-import io.spring.initializr.generator.BasicProjectRequest
-import io.spring.initializr.generator.CommandLineHelpGenerator
-import io.spring.initializr.generator.ProjectGenerator
-import io.spring.initializr.generator.ProjectRequest
-import io.spring.initializr.metadata.InitializrMetadataProvider
-import io.spring.initializr.util.Agent
-import io.spring.initializr.util.GroovyTemplate
-import io.spring.initializr.web.mapper.DependencyMetadataV21JsonMapper
-import io.spring.initializr.web.mapper.InitializrMetadataJsonMapper
-import io.spring.initializr.web.mapper.InitializrMetadataV21JsonMapper
-import io.spring.initializr.web.mapper.InitializrMetadataV2JsonMapper
-import io.spring.initializr.web.mapper.InitializrMetadataVersion
-import io.spring.initializr.metadata.DependencyMetadataProvider
-import io.spring.initializr.metadata.InitializrMetadata
-import io.spring.initializr.util.Version
-
-import org.springframework.http.CacheControl
-import org.springframework.http.HttpHeaders
-import org.springframework.http.MediaType
-import org.springframework.http.ResponseEntity
-import org.springframework.stereotype.Controller
-import org.springframework.util.DigestUtils
-import org.springframework.web.bind.annotation.ModelAttribute
-import org.springframework.web.bind.annotation.RequestHeader
-import org.springframework.web.bind.annotation.RequestMapping
-import org.springframework.web.bind.annotation.RequestParam
-import org.springframework.web.bind.annotation.ResponseBody
-
-import static io.spring.initializr.util.Agent.AgentId.CURL
-import static io.spring.initializr.util.Agent.AgentId.HTTPIE
-import static io.spring.initializr.util.Agent.AgentId.SPRING_BOOT_CLI
-
-/**
- * The main initializr controller provides access to the configured
- * metadata and serves as a central endpoint to generate projects
- * or build files.
- *
- * @author Dave Syer
- * @author Stephane Nicoll
- */
-@Controller
-@Slf4j
-class MainController extends AbstractInitializrController {
-
- static final MediaType HAL_JSON_CONTENT_TYPE = MediaType.parseMediaType('application/hal+json')
-
- private final ProjectGenerator projectGenerator
- private final DependencyMetadataProvider dependencyMetadataProvider
- private final CommandLineHelpGenerator commandLineHelpGenerator
-
- MainController(InitializrMetadataProvider metadataProvider, GroovyTemplate groovyTemplate,
- ResourceUrlProvider resourceUrlProvider, ProjectGenerator projectGenerator,
- DependencyMetadataProvider dependencyMetadataProvider) {
- super(metadataProvider, resourceUrlProvider, groovyTemplate)
- this.projectGenerator = projectGenerator
- this.dependencyMetadataProvider = dependencyMetadataProvider
- this.commandLineHelpGenerator = new CommandLineHelpGenerator(groovyTemplate)
- }
-
- @ModelAttribute
- BasicProjectRequest projectRequest(@RequestHeader Map headers) {
- def request = new ProjectRequest()
- request.parameters << headers
- request.initialize(metadataProvider.get())
- request
- }
-
- @RequestMapping(value = "/metadata/config", produces = ["application/json"])
- @ResponseBody
- InitializrMetadata config() {
- metadataProvider.get()
- }
-
- @RequestMapping(value = "/metadata/client")
- String client() {
- 'redirect:/'
- }
-
-
- @RequestMapping(value = "/", produces = ["text/plain"])
- ResponseEntity serviceCapabilitiesText(
- @RequestHeader(value = HttpHeaders.USER_AGENT, required = false) String userAgent) {
- String appUrl = generateAppUrl()
- def metadata = metadataProvider.get()
-
- def builder = ResponseEntity.ok().contentType(MediaType.TEXT_PLAIN)
- if (userAgent) {
- Agent agent = Agent.fromUserAgent(userAgent)
- if (CURL.equals(agent?.id)) {
- def content = commandLineHelpGenerator.generateCurlCapabilities(metadata, appUrl)
- return builder.eTag(createUniqueId(content)).body(content)
- }
- if (HTTPIE.equals(agent?.id)) {
- def content = commandLineHelpGenerator.generateHttpieCapabilities(metadata, appUrl)
- return builder.eTag(createUniqueId(content)).body(content)
- }
- if (SPRING_BOOT_CLI.equals(agent?.id)) {
- def content = commandLineHelpGenerator.generateSpringBootCliCapabilities(metadata, appUrl)
- return builder.eTag(createUniqueId(content)).body(content)
- }
- }
- def content = commandLineHelpGenerator.generateGenericCapabilities(metadata, appUrl)
- builder.eTag(createUniqueId(content)).body(content)
- }
-
- @RequestMapping(value = "/", produces = ["application/hal+json"])
- ResponseEntity serviceCapabilitiesHal() {
- serviceCapabilitiesFor(InitializrMetadataVersion.V2_1, HAL_JSON_CONTENT_TYPE)
- }
-
- @RequestMapping(value = "/", produces = ["application/vnd.initializr.v2.1+json", "application/json"])
- ResponseEntity serviceCapabilitiesV21() {
- serviceCapabilitiesFor(InitializrMetadataVersion.V2_1)
- }
-
- @RequestMapping(value = "/", produces = ["application/vnd.initializr.v2+json"])
- ResponseEntity serviceCapabilitiesV2() {
- serviceCapabilitiesFor(InitializrMetadataVersion.V2)
- }
-
- private ResponseEntity serviceCapabilitiesFor(InitializrMetadataVersion version) {
- serviceCapabilitiesFor(version, version.mediaType)
- }
-
- private ResponseEntity serviceCapabilitiesFor(InitializrMetadataVersion version, MediaType contentType) {
- String appUrl = generateAppUrl()
- def content = getJsonMapper(version).write(metadataProvider.get(), appUrl)
- return ResponseEntity.ok().contentType(contentType).eTag(createUniqueId(content))
- .cacheControl(CacheControl.maxAge(7, TimeUnit.DAYS)).body(content)
- }
-
- private static InitializrMetadataJsonMapper getJsonMapper(InitializrMetadataVersion version) {
- switch (version) {
- case InitializrMetadataVersion.V2: return new InitializrMetadataV2JsonMapper();
- default: return new InitializrMetadataV21JsonMapper();
- }
- }
-
- @RequestMapping(value = "/dependencies", produces = ["application/vnd.initializr.v2.1+json", "application/json"])
- ResponseEntity dependenciesV21(@RequestParam(required = false) String bootVersion) {
- dependenciesFor(InitializrMetadataVersion.V2_1, bootVersion)
- }
-
- private ResponseEntity dependenciesFor(InitializrMetadataVersion version, String bootVersion) {
- def metadata = metadataProvider.get()
- Version v = bootVersion != null ? Version.parse(bootVersion) :
- Version.parse(metadata.bootVersions.getDefault().id);
- def dependencyMetadata = dependencyMetadataProvider.get(metadata, v)
- def content = new DependencyMetadataV21JsonMapper().write(dependencyMetadata)
- return ResponseEntity.ok().contentType(version.mediaType).eTag(createUniqueId(content))
- .cacheControl(CacheControl.maxAge(7, TimeUnit.DAYS)).body(content)
- }
-
- @RequestMapping(value = '/', produces = 'text/html')
- @ResponseBody
- String home() {
- renderHome('home.html')
- }
-
- @RequestMapping('/spring')
- String spring() {
- def url = metadataProvider.get().createCliDistributionURl('zip')
- "redirect:$url"
- }
-
- @RequestMapping(value = ['/spring.tar.gz', 'spring.tgz'])
- String springTgz() {
- def url = metadataProvider.get().createCliDistributionURl('tar.gz')
- "redirect:$url"
- }
-
- @RequestMapping('/pom')
- @ResponseBody
- ResponseEntity pom(BasicProjectRequest request) {
- request.type = 'maven-build'
- def mavenPom = projectGenerator.generateMavenPom((ProjectRequest) request)
- createResponseEntity(mavenPom, 'application/octet-stream', 'pom.xml')
- }
-
- @RequestMapping('/build')
- @ResponseBody
- ResponseEntity gradle(BasicProjectRequest request) {
- request.type = 'gradle-build'
- def gradleBuild = projectGenerator.generateGradleBuild((ProjectRequest) request)
- createResponseEntity(gradleBuild, 'application/octet-stream', 'build.gradle')
- }
-
- @RequestMapping('/starter.zip')
- @ResponseBody
- ResponseEntity springZip(BasicProjectRequest basicRequest) {
- ProjectRequest request = (ProjectRequest) basicRequest
- def dir = projectGenerator.generateProjectStructure(request)
-
- def download = projectGenerator.createDistributionFile(dir, '.zip')
-
- def wrapperScript = getWrapperScript(request)
-
- new AntBuilder().zip(destfile: download) {
- zipfileset(dir: dir, includes: wrapperScript, filemode: 755)
- zipfileset(dir: dir, includes: '**,', excludes: wrapperScript, defaultexcludes: 'no')
- }
- upload(download, dir, generateFileName(request, 'zip'), 'application/zip')
- }
-
- @RequestMapping(value = '/starter.tgz', produces = 'application/x-compress')
- @ResponseBody
- ResponseEntity springTgz(BasicProjectRequest basicRequest) {
- ProjectRequest request = (ProjectRequest) basicRequest
- def dir = projectGenerator.generateProjectStructure(request)
-
- def download = projectGenerator.createDistributionFile(dir, '.tgz')
-
- def wrapperScript = getWrapperScript(request)
-
- new AntBuilder().tar(destfile: download, compression: 'gzip') {
- zipfileset(dir: dir, includes: wrapperScript, filemode: 755)
- zipfileset(dir: dir, includes: '**', excludes: wrapperScript, defaultexcludes: 'no')
- }
- upload(download, dir, generateFileName(request, 'tgz'), 'application/x-compress')
- }
-
- private static String generateFileName(ProjectRequest request, String extension) {
- String tmp = request.artifactId.replaceAll(' ', '_')
- URLEncoder.encode(tmp, 'UTF-8') + '.' + extension
- }
-
- private static String getWrapperScript(ProjectRequest request) {
- def script = 'gradle'.equals(request.build) ? 'gradlew' : 'mvnw'
- def wrapperScript = request.baseDir ? "$request.baseDir/$script" : script
- wrapperScript
- }
-
- private ResponseEntity upload(File download, File dir, String fileName, String contentType) {
- log.info("Uploading: ${download} (${download.bytes.length} bytes)")
- ResponseEntity result = createResponseEntity(download.bytes, contentType, fileName)
- projectGenerator.cleanTempFiles(dir)
- result
- }
-
- private ResponseEntity createResponseEntity(byte[] content, String contentType, String fileName) {
- String contentDispositionValue = "attachment; filename=\"$fileName\""
- ResponseEntity.ok()
- .header('Content-Type', contentType)
- .header('Content-Disposition', contentDispositionValue)
- .body(content);
- }
-
- private String createUniqueId(String content) {
- StringBuilder builder = new StringBuilder()
- DigestUtils.appendMd5DigestAsHex(content.getBytes(StandardCharsets.UTF_8), builder)
- builder.toString()
- }
-
-}
diff --git a/initializr-web/src/main/groovy/io/spring/initializr/web/support/DefaultDependencyMetadataProvider.groovy b/initializr-web/src/main/groovy/io/spring/initializr/web/support/DefaultDependencyMetadataProvider.groovy
deleted file mode 100644
index 3535808b..00000000
--- a/initializr-web/src/main/groovy/io/spring/initializr/web/support/DefaultDependencyMetadataProvider.groovy
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright 2012-2017 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.spring.initializr.web.support
-
-import io.spring.initializr.metadata.BillOfMaterials
-import io.spring.initializr.metadata.Dependency
-import io.spring.initializr.metadata.DependencyMetadata
-import io.spring.initializr.metadata.DependencyMetadataProvider
-import io.spring.initializr.metadata.InitializrMetadata
-import io.spring.initializr.metadata.Repository
-import io.spring.initializr.util.Version
-
-import org.springframework.cache.annotation.Cacheable
-
-/**
- * A default {@link DependencyMetadataProvider} implementation.
- *
- * @author Stephane Nicoll
- */
-class DefaultDependencyMetadataProvider implements DependencyMetadataProvider {
-
- @Override
- @Cacheable(cacheNames = "dependency-metadata", key = "#p1")
- DependencyMetadata get(InitializrMetadata metadata, Version bootVersion) {
- Map dependencies = [:]
- for (Dependency d : metadata.dependencies.getAll()) {
- if (d.match(bootVersion)) {
- dependencies[d.id] = d.resolve(bootVersion)
- }
- }
-
- Map repositories = [:]
- for (Dependency d : dependencies.values()) {
- if (d.repository) {
- repositories[d.repository] = metadata.configuration.env.repositories[d.repository]
- }
- }
-
- Map boms = [:]
- for (Dependency d : dependencies.values()) {
- if (d.bom) {
- boms[d.bom] = metadata.configuration.env.boms.get(d.bom).resolve(bootVersion)
- }
- }
- // Each resolved bom may require additional repositories
- for (BillOfMaterials b : boms.values()) {
- for (String id : b.repositories) {
- repositories[id] = metadata.configuration.env.repositories[id]
- }
- }
-
- return new DependencyMetadata(bootVersion, dependencies, repositories, boms)
- }
-
-}
diff --git a/initializr-web/src/main/groovy/io/spring/initializr/web/support/DefaultInitializrMetadataProvider.groovy b/initializr-web/src/main/groovy/io/spring/initializr/web/support/DefaultInitializrMetadataProvider.groovy
deleted file mode 100644
index 3ac398f1..00000000
--- a/initializr-web/src/main/groovy/io/spring/initializr/web/support/DefaultInitializrMetadataProvider.groovy
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright 2012-2017 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.spring.initializr.web.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.cache.annotation.Cacheable
-import org.springframework.web.client.RestTemplate
-
-/**
- * A default {@link InitializrMetadataProvider} that is able to refresh
- * the metadata with the status of the main spring.io site.
- *
- * @author Stephane Nicoll
- */
-@Slf4j
-class DefaultInitializrMetadataProvider implements InitializrMetadataProvider {
-
- private final InitializrMetadata metadata
- private final RestTemplate restTemplate
-
- DefaultInitializrMetadataProvider(InitializrMetadata metadata, RestTemplate restTemplate) {
- this.metadata = metadata
- this.restTemplate = restTemplate
- }
-
- @Override
- @Cacheable(value = 'initializr', key = "'metadata'")
- InitializrMetadata get() {
- updateInitializrMetadata(metadata)
- metadata
- }
-
- protected void updateInitializrMetadata(InitializrMetadata metadata) {
- def bootVersions = fetchBootVersions()
- if (bootVersions) {
- if (!bootVersions.find { it.default }) { // No default specified
- bootVersions[0].default = true
- }
- metadata.updateSpringBootVersions(bootVersions)
- }
- }
-
- protected List fetchBootVersions() {
- def url = metadata.configuration.env.springBootMetadataUrl
- if (url) {
- try {
- log.info("Fetching boot metadata from $url")
- return new SpringBootMetadataReader(restTemplate, url).bootVersions
- } catch (Exception e) {
- log.warn('Failed to fetch spring boot metadata', e)
- }
- }
- null
- }
-
-}
diff --git a/initializr-web/src/main/groovy/io/spring/initializr/web/support/SpringBootMetadataReader.groovy b/initializr-web/src/main/groovy/io/spring/initializr/web/support/SpringBootMetadataReader.groovy
deleted file mode 100644
index a69bb10b..00000000
--- a/initializr-web/src/main/groovy/io/spring/initializr/web/support/SpringBootMetadataReader.groovy
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright 2012-2017 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.spring.initializr.web.support
-
-import groovy.json.JsonSlurper
-import io.spring.initializr.metadata.DefaultMetadataElement
-
-import org.springframework.web.client.RestTemplate
-
-/**
- * Reads metadata from the main spring.io website. This is a stateful
- * service: creates a new instance whenever you need to refresh the
- * content.
- *
- * @author Stephane Nicoll
- */
-class SpringBootMetadataReader {
-
- private final def content
-
- /**
- * Parse the content of the metadata at the specified url
- */
- SpringBootMetadataReader(RestTemplate restTemplate, String url) {
- def content = restTemplate.getForObject(url, String.class)
- this.content = new JsonSlurper().parseText(content)
- }
-
- /**
- * Return the boot versions parsed by this instance.
- */
- List getBootVersions() {
- content.projectReleases.collect {
- def version = new DefaultMetadataElement()
- version.id = it.version
- def name = it.versionDisplayName
- version.name = (it.snapshot ? name + ' (SNAPSHOT)' : name)
- version.setDefault(it.current)
- version
- }
- }
-
-}
diff --git a/initializr-web/src/main/groovy/io/spring/initializr/web/ui/UiController.groovy b/initializr-web/src/main/groovy/io/spring/initializr/web/ui/UiController.groovy
deleted file mode 100644
index 4bc97cc4..00000000
--- a/initializr-web/src/main/groovy/io/spring/initializr/web/ui/UiController.groovy
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright 2012-2017 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.spring.initializr.web.ui
-
-import java.nio.charset.StandardCharsets
-
-import groovy.json.JsonBuilder
-import io.spring.initializr.metadata.Dependency
-import io.spring.initializr.metadata.InitializrMetadataProvider
-import io.spring.initializr.util.Version
-
-import org.springframework.beans.factory.annotation.Autowired
-import org.springframework.http.MediaType
-import org.springframework.http.ResponseEntity
-import org.springframework.util.DigestUtils
-import org.springframework.web.bind.annotation.RequestMapping
-import org.springframework.web.bind.annotation.RequestParam
-import org.springframework.web.bind.annotation.RestController
-
-/**
- * UI specific controller providing dedicated endpoints for the Web UI.
- *
- * @author Stephane Nicoll
- */
-@RestController
-class UiController {
-
- @Autowired
- protected InitializrMetadataProvider metadataProvider
-
- @RequestMapping(value = "/ui/dependencies", produces = ["application/json"])
- ResponseEntity dependencies(@RequestParam(required = false) String version) {
- def dependencyGroups = metadataProvider.get().dependencies.content
- def content = []
- Version v = version ? Version.parse(version) : null
- dependencyGroups.each { g ->
- g.content.each { d ->
- if (v && d.versionRange) {
- if (d.match(v)) {
- content << new DependencyItem(g.name, d)
- }
- } else {
- content << new DependencyItem(g.name, d)
- }
- }
- }
- def json = writeDependencies(content)
- ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).
- eTag(createUniqueId(json)).body(json)
- }
-
- private static String writeDependencies(List items) {
- JsonBuilder json = new JsonBuilder();
- json {
- dependencies items.collect { d ->
- mapDependency(d)
- }
- }
- json.toString()
- }
-
- private static mapDependency(DependencyItem item) {
- def result = [:]
- Dependency d = item.dependency
- result.id = d.id
- result.name = d.name
- result.group = item.group
- if (d.description) {
- result.description = d.description
- }
- if (d.weight) {
- result.weight = d.weight
- }
- if (d.keywords || d.aliases) {
- def all = d.keywords + d.aliases
- result.keywords = all.join(',')
- }
- result
- }
-
- private static class DependencyItem {
- private final String group
- private final Dependency dependency
-
- DependencyItem(String group, Dependency dependency) {
- this.group = group
- this.dependency = dependency
- }
- }
-
- private String createUniqueId(String content) {
- StringBuilder builder = new StringBuilder()
- DigestUtils.appendMd5DigestAsHex(content.getBytes(StandardCharsets.UTF_8), builder)
- builder.toString()
- }
-
-}
diff --git a/initializr-web/src/main/groovy/io/spring/initializr/web/autoconfigure/CloudfoundryEnvironmentPostProcessor.groovy b/initializr-web/src/main/java/io/spring/initializr/web/autoconfigure/CloudfoundryEnvironmentPostProcessor.java
similarity index 57%
rename from initializr-web/src/main/groovy/io/spring/initializr/web/autoconfigure/CloudfoundryEnvironmentPostProcessor.groovy
rename to initializr-web/src/main/java/io/spring/initializr/web/autoconfigure/CloudfoundryEnvironmentPostProcessor.java
index 9bac0094..5a3b430a 100644
--- a/initializr-web/src/main/groovy/io/spring/initializr/web/autoconfigure/CloudfoundryEnvironmentPostProcessor.groovy
+++ b/initializr-web/src/main/java/io/spring/initializr/web/autoconfigure/CloudfoundryEnvironmentPostProcessor.java
@@ -14,19 +14,22 @@
* limitations under the License.
*/
-package io.spring.initializr.web.autoconfigure
+package io.spring.initializr.web.autoconfigure;
-import org.springframework.boot.SpringApplication
-import org.springframework.boot.context.config.ConfigFileApplicationListener
-import org.springframework.boot.env.EnvironmentPostProcessor
-import org.springframework.core.Ordered
-import org.springframework.core.env.ConfigurableEnvironment
-import org.springframework.core.env.MapPropertySource
-import org.springframework.core.env.MutablePropertySources
-import org.springframework.core.env.PropertySource
-import org.springframework.util.StringUtils
-import org.springframework.web.util.UriComponents
-import org.springframework.web.util.UriComponentsBuilder
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.context.config.ConfigFileApplicationListener;
+import org.springframework.boot.env.EnvironmentPostProcessor;
+import org.springframework.core.Ordered;
+import org.springframework.core.env.ConfigurableEnvironment;
+import org.springframework.core.env.MapPropertySource;
+import org.springframework.core.env.MutablePropertySources;
+import org.springframework.core.env.PropertySource;
+import org.springframework.util.StringUtils;
+import org.springframework.web.util.UriComponents;
+import org.springframework.web.util.UriComponentsBuilder;
/**
* Post-process the environment to extract the service credentials provided by
@@ -34,7 +37,8 @@ import org.springframework.web.util.UriComponentsBuilder
*
* @author Stephane Nicoll
*/
-class CloudfoundryEnvironmentPostProcessor implements EnvironmentPostProcessor, Ordered {
+public class CloudfoundryEnvironmentPostProcessor
+ implements EnvironmentPostProcessor, Ordered {
private static final String PROPERTY_SOURCE_NAME = "defaultProperties";
@@ -44,18 +48,18 @@ class CloudfoundryEnvironmentPostProcessor implements EnvironmentPostProcessor,
public void postProcessEnvironment(ConfigurableEnvironment environment,
SpringApplication springApplication) {
- Map map = [:]
- String uri = environment.getProperty('vcap.services.stats-index.credentials.uri')
+ Map map = new LinkedHashMap<>();
+ String uri = environment.getProperty("vcap.services.stats-index.credentials.uri");
if (StringUtils.hasText(uri)) {
- UriComponents uriComponents = UriComponentsBuilder.fromUriString(uri).build()
- def userInfo = uriComponents.getUserInfo()
- if (userInfo) {
- String[] credentials = userInfo.split(':')
- map['initializr.stats.elastic.username'] = credentials[0]
- map['initializr.stats.elastic.password'] = credentials[1]
+ UriComponents uriComponents = UriComponentsBuilder.fromUriString(uri).build();
+ String userInfo = uriComponents.getUserInfo();
+ if (StringUtils.hasText(userInfo)) {
+ String[] credentials = userInfo.split(":");
+ map.put("initializr.stats.elastic.username", credentials[0]);
+ map.put("initializr.stats.elastic.password", credentials[1]);
}
- map['initializr.stats.elastic.uri'] = UriComponentsBuilder.fromUriString(uri)
- .userInfo(null).build().toString()
+ map.put("initializr.stats.elastic.uri", UriComponentsBuilder.fromUriString(uri)
+ .userInfo(null).build().toString());
addOrReplace(environment.getPropertySources(), map);
}
@@ -63,19 +67,19 @@ class CloudfoundryEnvironmentPostProcessor implements EnvironmentPostProcessor,
@Override
public int getOrder() {
- return this.order
+ return this.order;
}
private static void addOrReplace(MutablePropertySources propertySources,
Map map) {
- MapPropertySource target = null
+ MapPropertySource target = null;
if (propertySources.contains(PROPERTY_SOURCE_NAME)) {
- PropertySource> source = propertySources.get(PROPERTY_SOURCE_NAME)
+ PropertySource> source = propertySources.get(PROPERTY_SOURCE_NAME);
if (source instanceof MapPropertySource) {
- target = (MapPropertySource) source
+ target = (MapPropertySource) source;
for (String key : map.keySet()) {
if (!target.containsProperty(key)) {
- target.getSource().put(key, map.get(key))
+ target.getSource().put(key, map.get(key));
}
}
}
diff --git a/initializr-web/src/main/java/io/spring/initializr/web/autoconfigure/InitializrAutoConfiguration.java b/initializr-web/src/main/java/io/spring/initializr/web/autoconfigure/InitializrAutoConfiguration.java
new file mode 100644
index 00000000..97bb689e
--- /dev/null
+++ b/initializr-web/src/main/java/io/spring/initializr/web/autoconfigure/InitializrAutoConfiguration.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright 2012-2017 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.spring.initializr.web.autoconfigure;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.bind.RelaxedPropertyResolver;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.cache.Cache;
+import org.springframework.cache.CacheManager;
+import org.springframework.cache.annotation.EnableCaching;
+import org.springframework.cache.caffeine.CaffeineCache;
+import org.springframework.cache.concurrent.ConcurrentMapCache;
+import org.springframework.cache.support.SimpleCacheManager;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.env.Environment;
+import org.springframework.web.client.RestTemplate;
+import org.springframework.web.servlet.resource.ResourceUrlProvider;
+
+import com.github.benmanes.caffeine.cache.Caffeine;
+
+import io.spring.initializr.generator.ProjectGenerator;
+import io.spring.initializr.generator.ProjectRequestPostProcessor;
+import io.spring.initializr.generator.ProjectRequestResolver;
+import io.spring.initializr.generator.ProjectResourceLocator;
+import io.spring.initializr.metadata.DependencyMetadataProvider;
+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.util.GroovyTemplate;
+import io.spring.initializr.web.project.MainController;
+import io.spring.initializr.web.support.DefaultDependencyMetadataProvider;
+import io.spring.initializr.web.support.DefaultInitializrMetadataProvider;
+import io.spring.initializr.web.ui.UiController;
+
+/**
+ * {@link org.springframework.boot.autoconfigure.EnableAutoConfiguration
+ * Auto-configuration} to configure Spring initializr. In a web environment,
+ * configures the necessary controller to serve the applications from the
+ * root context.
+ *
+ * Project generation can be customized by defining a custom
+ * {@link ProjectGenerator}.
+ *
+ * @author Stephane Nicoll
+ */
+@Configuration
+@EnableCaching
+@EnableConfigurationProperties(InitializrProperties.class)
+public class InitializrAutoConfiguration {
+
+ @Autowired(required = false)
+ private List postProcessors = new ArrayList<>();
+
+ @Bean
+ public WebConfig webConfig() {
+ return new WebConfig();
+ }
+
+ @Bean
+ @ConditionalOnMissingBean
+ public MainController initializrMainController(InitializrMetadataProvider metadataProvider,
+ GroovyTemplate groovyTemplate,
+ ResourceUrlProvider resourceUrlProvider,
+ ProjectGenerator projectGenerator,
+ DependencyMetadataProvider dependencyMetadataProvider) {
+ return new MainController(metadataProvider, groovyTemplate, resourceUrlProvider
+ , projectGenerator, dependencyMetadataProvider);
+ }
+
+ @Bean
+ @ConditionalOnMissingBean
+ public UiController initializrUiController() {
+ return new UiController();
+ }
+
+ @Bean
+ @ConditionalOnMissingBean
+ public ProjectGenerator projectGenerator() {
+ return new ProjectGenerator();
+ }
+
+ @Bean
+ @ConditionalOnMissingBean
+ public GroovyTemplate groovyTemplate(Environment environment) {
+ RelaxedPropertyResolver resolver = new RelaxedPropertyResolver(environment, "spring.groovy.template.");
+ boolean cache = resolver.getProperty("cache", Boolean.class, true);
+ GroovyTemplate groovyTemplate = new GroovyTemplate();
+ groovyTemplate.setCache(cache);
+ return groovyTemplate;
+ }
+
+ @Bean
+ @ConditionalOnMissingBean
+ public ProjectRequestResolver projectRequestResolver() {
+ return new ProjectRequestResolver(postProcessors);
+ }
+
+ @Bean
+ public ProjectResourceLocator projectResourceLocator() {
+ return new ProjectResourceLocator();
+ }
+
+ @Bean
+ @ConditionalOnMissingBean(InitializrMetadataProvider.class)
+ public InitializrMetadataProvider initializrMetadataProvider(InitializrProperties properties) {
+ InitializrMetadata metadata = InitializrMetadataBuilder.fromInitializrProperties(properties).build();
+ return new DefaultInitializrMetadataProvider(metadata, new RestTemplate());
+ }
+
+ @Bean
+ @ConditionalOnMissingBean
+ public DependencyMetadataProvider dependencyMetadataProvider() {
+ return new DefaultDependencyMetadataProvider();
+ }
+
+ @Bean
+ @ConditionalOnMissingBean
+ public CacheManager cacheManager() {
+ SimpleCacheManager cacheManager = new SimpleCacheManager();
+ cacheManager.setCaches(Arrays.asList(
+ createConcurrentMapCache(600L, "initializr"),
+ new ConcurrentMapCache("dependency-metadata"),
+ new ConcurrentMapCache("project-resources")));
+ return cacheManager;
+ }
+
+ private static Cache createConcurrentMapCache(Long timeToLive, String name) {
+ return new CaffeineCache(name, Caffeine
+ .newBuilder()
+ .expireAfterWrite(timeToLive, TimeUnit.SECONDS)
+ .build());
+ }
+
+}
diff --git a/initializr-web/src/main/groovy/io/spring/initializr/web/autoconfigure/WebConfig.groovy b/initializr-web/src/main/java/io/spring/initializr/web/autoconfigure/WebConfig.java
similarity index 56%
rename from initializr-web/src/main/groovy/io/spring/initializr/web/autoconfigure/WebConfig.groovy
rename to initializr-web/src/main/java/io/spring/initializr/web/autoconfigure/WebConfig.java
index d9d9b153..d96714e8 100644
--- a/initializr-web/src/main/groovy/io/spring/initializr/web/autoconfigure/WebConfig.groovy
+++ b/initializr-web/src/main/java/io/spring/initializr/web/autoconfigure/WebConfig.java
@@ -14,34 +14,36 @@
* limitations under the License.
*/
-package io.spring.initializr.web.autoconfigure
+package io.spring.initializr.web.autoconfigure;
-import javax.servlet.http.HttpServletRequest
+import java.util.Collections;
+import java.util.List;
-import io.spring.initializr.util.Agent
+import javax.servlet.http.HttpServletRequest;
-import org.springframework.http.HttpHeaders
-import org.springframework.http.MediaType
-import org.springframework.web.HttpMediaTypeNotAcceptableException
-import org.springframework.web.accept.ContentNegotiationStrategy
-import org.springframework.web.context.request.NativeWebRequest
-import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer
-import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter
-import org.springframework.web.util.UrlPathHelper
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
+import org.springframework.util.StringUtils;
+import org.springframework.web.HttpMediaTypeNotAcceptableException;
+import org.springframework.web.accept.ContentNegotiationStrategy;
+import org.springframework.web.context.request.NativeWebRequest;
+import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
+import org.springframework.web.util.UrlPathHelper;
-import static io.spring.initializr.util.Agent.AgentId.CURL
-import static io.spring.initializr.util.Agent.AgentId.HTTPIE
+import io.spring.initializr.util.Agent;
+import io.spring.initializr.util.Agent.AgentId;
/**
* Spring Initializr web configuration.
*
* @author Stephane Nicoll
*/
-class WebConfig extends WebMvcConfigurerAdapter {
+public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
- configurer.defaultContentTypeStrategy(new CommandLineContentNegotiationStrategy())
+ configurer.defaultContentTypeStrategy(new CommandLineContentNegotiationStrategy());
}
/**
@@ -53,20 +55,22 @@ class WebConfig extends WebMvcConfigurerAdapter {
private final UrlPathHelper urlPathHelper = new UrlPathHelper();
@Override
- List resolveMediaTypes(NativeWebRequest request) throws HttpMediaTypeNotAcceptableException {
+ public List resolveMediaTypes(NativeWebRequest request) throws HttpMediaTypeNotAcceptableException {
String path = urlPathHelper.getPathWithinApplication(
request.getNativeRequest(HttpServletRequest.class));
- if (!path || !path.equals("/")) { // Only care about "/"
- return Collections.emptyList()
+ if (!StringUtils.hasText(path) || !path.equals("/")) { // Only care about "/"
+ return Collections.emptyList();
}
- String userAgent = request.getHeader(HttpHeaders.USER_AGENT)
- if (userAgent) {
- Agent agent = Agent.fromUserAgent(userAgent)
- if (CURL.equals(agent?.id) || HTTPIE.equals(agent?.id)) {
- return Collections.singletonList(MediaType.TEXT_PLAIN)
+ String userAgent = request.getHeader(HttpHeaders.USER_AGENT);
+ if (userAgent!=null) {
+ Agent agent = Agent.fromUserAgent(userAgent);
+ if (agent!=null) {
+ if (AgentId.CURL.equals(agent.getId()) || AgentId.HTTPIE.equals(agent.getId())) {
+ return Collections.singletonList(MediaType.TEXT_PLAIN);
+ }
}
}
- return Collections.singletonList(MediaType.APPLICATION_JSON)
+ return Collections.singletonList(MediaType.APPLICATION_JSON);
}
}
diff --git a/initializr-web/src/main/groovy/io/spring/initializr/web/mapper/DependencyMetadataJsonMapper.groovy b/initializr-web/src/main/java/io/spring/initializr/web/mapper/DependencyMetadataJsonMapper.java
similarity index 89%
rename from initializr-web/src/main/groovy/io/spring/initializr/web/mapper/DependencyMetadataJsonMapper.groovy
rename to initializr-web/src/main/java/io/spring/initializr/web/mapper/DependencyMetadataJsonMapper.java
index 9c6f4d70..d65b512c 100644
--- a/initializr-web/src/main/groovy/io/spring/initializr/web/mapper/DependencyMetadataJsonMapper.groovy
+++ b/initializr-web/src/main/java/io/spring/initializr/web/mapper/DependencyMetadataJsonMapper.java
@@ -14,9 +14,9 @@
* limitations under the License.
*/
-package io.spring.initializr.web.mapper
+package io.spring.initializr.web.mapper;
-import io.spring.initializr.metadata.DependencyMetadata
+import io.spring.initializr.metadata.DependencyMetadata;
/**
* Generate a JSON representation of a set of dependencies.
diff --git a/initializr-web/src/main/java/io/spring/initializr/web/mapper/DependencyMetadataV21JsonMapper.java b/initializr-web/src/main/java/io/spring/initializr/web/mapper/DependencyMetadataV21JsonMapper.java
new file mode 100644
index 00000000..f76c2925
--- /dev/null
+++ b/initializr-web/src/main/java/io/spring/initializr/web/mapper/DependencyMetadataV21JsonMapper.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2012-2017 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.spring.initializr.web.mapper;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import org.json.JSONObject;
+
+import io.spring.initializr.metadata.BillOfMaterials;
+import io.spring.initializr.metadata.Dependency;
+import io.spring.initializr.metadata.DependencyMetadata;
+import io.spring.initializr.metadata.Repository;
+
+/**
+ * A {@link DependencyMetadataJsonMapper} handling the metadata format for v2.1.
+ *
+ * @author Stephane Nicoll
+ */
+public class DependencyMetadataV21JsonMapper implements DependencyMetadataJsonMapper {
+
+ @Override
+ public String write(DependencyMetadata metadata) {
+ JSONObject json = new JSONObject();
+ json.put("bootVersion", metadata.getBootVersion().toString());
+ json.put("dependencies",
+ metadata.getDependencies().entrySet().stream()
+ .collect(Collectors.toMap(entry -> entry.getKey(),
+ entry -> mapDependency(entry.getValue()))));
+ json.put("repositories",
+ metadata.getRepositories().entrySet().stream()
+ .collect(Collectors.toMap(entry -> entry.getKey(),
+ entry -> mapRepository(entry.getValue()))));
+ json.put("boms", metadata.getBoms().entrySet().stream().collect(Collectors
+ .toMap(entry -> entry.getKey(), entry -> mapBom(entry.getValue()))));
+ return json.toString();
+ }
+
+ private static Map mapDependency(Dependency dep) {
+ Map result = new LinkedHashMap<>();
+ result.put("groupId", dep.getGroupId());
+ result.put("artifactId", dep.getArtifactId());
+ if (dep.getVersion() != null) {
+ result.put("version", dep.getVersion());
+ }
+ result.put("scope", dep.getScope());
+ if (dep.getBom() != null) {
+ result.put("bom", dep.getBom());
+ }
+ if (dep.getRepository() != null) {
+ result.put("repository", dep.getRepository());
+ }
+ return result;
+ }
+
+ private static Map mapRepository(Repository repo) {
+ Map result = new LinkedHashMap<>();
+ result.put("name", repo.getName());
+ result.put("url", repo.getUrl());
+ result.put("snapshotEnabled", repo.isSnapshotsEnabled());
+ return result;
+ }
+
+ private static Map mapBom(BillOfMaterials bom) {
+ Map result = new LinkedHashMap<>();
+ result.put("groupId", bom.getGroupId());
+ result.put("artifactId", bom.getArtifactId());
+ if (bom.getVersion() != null) {
+ result.put("version", bom.getVersion());
+ }
+ if (bom.getRepositories() != null) {
+ result.put("repositories", bom.getRepositories());
+ }
+ return result;
+ }
+
+}
diff --git a/initializr-web/src/main/groovy/io/spring/initializr/web/mapper/InitializrMetadataJsonMapper.groovy b/initializr-web/src/main/java/io/spring/initializr/web/mapper/InitializrMetadataJsonMapper.java
similarity index 85%
rename from initializr-web/src/main/groovy/io/spring/initializr/web/mapper/InitializrMetadataJsonMapper.groovy
rename to initializr-web/src/main/java/io/spring/initializr/web/mapper/InitializrMetadataJsonMapper.java
index 13ca53e5..99774673 100644
--- a/initializr-web/src/main/groovy/io/spring/initializr/web/mapper/InitializrMetadataJsonMapper.groovy
+++ b/initializr-web/src/main/java/io/spring/initializr/web/mapper/InitializrMetadataJsonMapper.java
@@ -14,16 +14,16 @@
* limitations under the License.
*/
-package io.spring.initializr.web.mapper
+package io.spring.initializr.web.mapper;
-import io.spring.initializr.metadata.InitializrMetadata
+import io.spring.initializr.metadata.InitializrMetadata;
/**
* Generate a JSON representation of the metadata.
*
* @author Stephane Nicoll
*/
-interface InitializrMetadataJsonMapper {
+public interface InitializrMetadataJsonMapper {
/**
* Write a json representation of the specified metadata.
diff --git a/initializr-web/src/main/java/io/spring/initializr/web/mapper/InitializrMetadataV21JsonMapper.java b/initializr-web/src/main/java/io/spring/initializr/web/mapper/InitializrMetadataV21JsonMapper.java
new file mode 100644
index 00000000..88bc9a2b
--- /dev/null
+++ b/initializr-web/src/main/java/io/spring/initializr/web/mapper/InitializrMetadataV21JsonMapper.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2012-2017 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.spring.initializr.web.mapper;
+
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.json.JSONObject;
+import org.springframework.hateoas.TemplateVariable;
+import org.springframework.hateoas.TemplateVariables;
+import org.springframework.hateoas.UriTemplate;
+
+import io.spring.initializr.metadata.Dependency;
+import io.spring.initializr.metadata.Type;
+
+/**
+ * A {@link InitializrMetadataJsonMapper} handling the metadata format for v2.1
+ *
+ * Version 2.1 brings the "versionRange" attribute for a dependency to restrict
+ * the Spring Boot versions that can be used against it. That version also adds
+ * an additional `dependencies` endpoint.
+ *
+ * @author Stephane Nicoll
+ */
+public class InitializrMetadataV21JsonMapper extends InitializrMetadataV2JsonMapper {
+
+ private final TemplateVariables dependenciesVariables;
+
+ public InitializrMetadataV21JsonMapper() {
+ this.dependenciesVariables = new TemplateVariables(
+ new TemplateVariable("bootVersion", TemplateVariable.VariableType.REQUEST_PARAM)
+ );
+ }
+
+ @Override
+ protected Map links(JSONObject parent, List types, String appUrl) {
+ Map links = super.links(parent, types, appUrl);
+ links.put("dependencies", dependenciesLink(appUrl));
+ parent.put("_links", links);
+ return links;
+ }
+
+ @Override
+ protected Map mapDependency(Dependency dependency) {
+ Map content = mapValue(dependency);
+ if (dependency.getVersionRange()!=null) {
+ content.put("versionRange", dependency.getVersionRange());
+ }
+ if (dependency.getLinks()!=null && !dependency.getLinks().isEmpty()) {
+ content.put("_links", LinkMapper.mapLinks(dependency.getLinks()));
+ }
+ return content;
+ }
+
+ private Map dependenciesLink(String appUrl) {
+ String uri = appUrl != null ? appUrl + "/dependencies" : "/dependencies";
+ UriTemplate uriTemplate = new UriTemplate(uri, this.dependenciesVariables);
+ Map result = new LinkedHashMap<>();
+ result.put("href", uriTemplate.toString());
+ result.put("templated", true);
+ return result;
+ }
+}
diff --git a/initializr-web/src/main/java/io/spring/initializr/web/mapper/InitializrMetadataV2JsonMapper.java b/initializr-web/src/main/java/io/spring/initializr/web/mapper/InitializrMetadataV2JsonMapper.java
new file mode 100644
index 00000000..0f4a1071
--- /dev/null
+++ b/initializr-web/src/main/java/io/spring/initializr/web/mapper/InitializrMetadataV2JsonMapper.java
@@ -0,0 +1,203 @@
+/*
+ * Copyright 2012-2017 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.spring.initializr.web.mapper;
+
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import org.json.JSONObject;
+import org.springframework.hateoas.TemplateVariable;
+import org.springframework.hateoas.TemplateVariables;
+import org.springframework.hateoas.UriTemplate;
+import org.springframework.util.StringUtils;
+
+import io.spring.initializr.metadata.DefaultMetadataElement;
+import io.spring.initializr.metadata.DependenciesCapability;
+import io.spring.initializr.metadata.Dependency;
+import io.spring.initializr.metadata.DependencyGroup;
+import io.spring.initializr.metadata.Describable;
+import io.spring.initializr.metadata.InitializrMetadata;
+import io.spring.initializr.metadata.MetadataElement;
+import io.spring.initializr.metadata.SingleSelectCapability;
+import io.spring.initializr.metadata.TextCapability;
+import io.spring.initializr.metadata.Type;
+import io.spring.initializr.metadata.TypeCapability;
+
+/**
+ * A {@link InitializrMetadataJsonMapper} handling the metadata format for v2.
+ *
+ * @author Stephane Nicoll
+ */
+public class InitializrMetadataV2JsonMapper implements InitializrMetadataJsonMapper {
+
+ private final TemplateVariables templateVariables;
+
+ public InitializrMetadataV2JsonMapper() {
+ this.templateVariables = new TemplateVariables(
+ new TemplateVariable("dependencies",
+ TemplateVariable.VariableType.REQUEST_PARAM),
+ new TemplateVariable("packaging",
+ TemplateVariable.VariableType.REQUEST_PARAM),
+ new TemplateVariable("javaVersion",
+ TemplateVariable.VariableType.REQUEST_PARAM),
+ new TemplateVariable("language",
+ TemplateVariable.VariableType.REQUEST_PARAM),
+ new TemplateVariable("bootVersion",
+ TemplateVariable.VariableType.REQUEST_PARAM),
+ new TemplateVariable("groupId",
+ TemplateVariable.VariableType.REQUEST_PARAM),
+ new TemplateVariable("artifactId",
+ TemplateVariable.VariableType.REQUEST_PARAM),
+ new TemplateVariable("version",
+ TemplateVariable.VariableType.REQUEST_PARAM),
+ new TemplateVariable("name", TemplateVariable.VariableType.REQUEST_PARAM),
+ new TemplateVariable("description",
+ TemplateVariable.VariableType.REQUEST_PARAM),
+ new TemplateVariable("packageName",
+ TemplateVariable.VariableType.REQUEST_PARAM));
+ }
+
+ @Override
+ public String write(InitializrMetadata metadata, String appUrl) {
+ JSONObject delegate = new JSONObject();
+ links(delegate, metadata.getTypes().getContent(), appUrl);
+ dependencies(delegate, metadata.getDependencies());
+ type(delegate, metadata.getTypes());
+ singleSelect(delegate, metadata.getPackagings());
+ singleSelect(delegate, metadata.getJavaVersions());
+ singleSelect(delegate, metadata.getLanguages());
+ singleSelect(delegate, metadata.getBootVersions());
+ text(delegate, metadata.getGroupId());
+ text(delegate, metadata.getArtifactId());
+ text(delegate, metadata.getVersion());
+ text(delegate, metadata.getName());
+ text(delegate, metadata.getDescription());
+ text(delegate, metadata.getPackageName());
+ return delegate.toString();
+ }
+
+ protected Map links(JSONObject parent, List types, String appUrl) {
+ Map content = new LinkedHashMap<>();
+ types.forEach(it -> {
+ content.put(it.getId(), link(appUrl, it));
+ });
+ parent.put("_links", content);
+ return content;
+ }
+
+ protected Map link(String appUrl, Type type) {
+ Map result = new LinkedHashMap<>();
+ result.put("href", generateTemplatedUri(appUrl, type));
+ result.put("templated", true);
+ return result;
+ }
+
+ private String generateTemplatedUri(String appUrl, Type type) {
+ String uri = appUrl != null ? appUrl + type.getAction() : type.getAction();
+ uri = uri + "?type=" + type.getId();
+ UriTemplate uriTemplate = new UriTemplate(uri, this.templateVariables);
+ return uriTemplate.toString();
+ }
+
+ protected void dependencies(JSONObject parent, DependenciesCapability capability) {
+ Map map = new LinkedHashMap<>();
+ map.put("type", capability.getType().getName());
+ map.put("values",
+ capability.getContent().stream().map(it -> mapDependencyGroup(it)).collect(Collectors.toList()));
+ parent.put(capability.getId(), map);
+ }
+
+ protected void type(JSONObject parent, TypeCapability capability) {
+ Map map = new LinkedHashMap<>();
+ map.put("type", "action");
+ Type defaultType = capability.getDefault();
+ if (defaultType != null) {
+ map.put("default", defaultType.getId());
+ }
+ map.put("values", capability.getContent().stream().map(it -> mapType(it))
+ .collect(Collectors.toList()));
+ parent.put("type", map);
+ }
+
+ protected void singleSelect(JSONObject parent, SingleSelectCapability capability) {
+ Map map = new LinkedHashMap<>();
+ map.put("type", capability.getType().getName());
+ DefaultMetadataElement defaultType = capability.getDefault();
+ if (defaultType != null) {
+ map.put("default", defaultType.getId());
+ }
+ map.put("values", capability.getContent().stream().map(it -> mapValue(it))
+ .collect(Collectors.toList()));
+ parent.put(capability.getId(), map);
+ }
+
+ protected void text(JSONObject parent, TextCapability capability) {
+ Map map = new LinkedHashMap<>();
+ map.put("type", capability.getType().getName());
+ String defaultValue = capability.getContent();
+ if (StringUtils.hasText(defaultValue)) {
+ map.put("default", defaultValue);
+ }
+ parent.put(capability.getId(), map);
+ }
+
+ protected Map mapDependencyGroup(DependencyGroup group) {
+ Map result = new LinkedHashMap<>();
+ result.put("name", group.getName());
+ if ((group instanceof Describable) && ((Describable) group).getDescription() != null) {
+ result.put("description", ((Describable) group).getDescription());
+ }
+ List
-
+
- <% dependencies.content.each { %>
+ {{#dependencies.content}}
-
-
-
-
-<% if (trackingCode) { %>
+
+
+
+
+{{#trackingCode}}
<% } %>
+
+{{/trackingCode}}