mirror of
https://gitee.com/dcren/initializr.git
synced 2025-11-08 18:34:58 +08:00
Update metadata format to v2
Update the metadata format in a non backward compatible way to ease the use of the service from 3rd party clients. The updated metadata format is now more descriptive and HAL-compliant and can be used with Spring HATEOAS to build a client. Metadata v1 is still served to preserve backward compatibility with Spring Boot 1.2.0.RC1. Closes gh-49
This commit is contained in:
@@ -30,6 +30,10 @@
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.hateoas</groupId>
|
||||
<artifactId>spring-hateoas</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
|
||||
@@ -66,6 +66,8 @@ class InitializrMetadata {
|
||||
@JsonIgnore
|
||||
private final Map<String, Dependency> indexedDependencies = [:]
|
||||
|
||||
private final transient InitializrMetadataJsonMapper jsonMapper = new InitializrMetadataJsonMapper()
|
||||
|
||||
/**
|
||||
* Return the {@link Dependency} with the specified id or {@code null} if
|
||||
* no such dependency exists.
|
||||
@@ -121,6 +123,15 @@ class InitializrMetadata {
|
||||
refreshDefaults()
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a JSON representation of the current metadata
|
||||
*
|
||||
* @param appUrl the application url
|
||||
*/
|
||||
String generateJson(String appUrl) {
|
||||
jsonMapper.write(this, appUrl)
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize and validate the configuration.
|
||||
*/
|
||||
@@ -261,6 +272,14 @@ class InitializrMetadata {
|
||||
|
||||
String action
|
||||
|
||||
void setAction(String action) {
|
||||
String actionToUse = action
|
||||
if (!actionToUse.startsWith("/")) {
|
||||
actionToUse = "/" + actionToUse
|
||||
}
|
||||
this.action = actionToUse
|
||||
}
|
||||
|
||||
final Map<String, String> tags = [:]
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
* Copyright 2012-2014 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 groovy.json.JsonBuilder
|
||||
|
||||
import org.springframework.hateoas.TemplateVariable
|
||||
import org.springframework.hateoas.TemplateVariables
|
||||
import org.springframework.hateoas.UriTemplate
|
||||
|
||||
/**
|
||||
* Generate a JSON representation of the metadata.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @since 1.0
|
||||
*/
|
||||
class InitializrMetadataJsonMapper {
|
||||
|
||||
private final TemplateVariables templateVariables
|
||||
|
||||
InitializrMetadataJsonMapper() {
|
||||
this.templateVariables = new TemplateVariables(
|
||||
new TemplateVariable('type', 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)
|
||||
)
|
||||
}
|
||||
|
||||
String write(InitializrMetadata metadata, String appUrl) {
|
||||
JsonBuilder json = new JsonBuilder()
|
||||
json {
|
||||
links(delegate, metadata.types, 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)
|
||||
}
|
||||
json.toString()
|
||||
}
|
||||
|
||||
private links(parent, types, appUrl) {
|
||||
def content = [:]
|
||||
types.each {
|
||||
content[it.id] = link(appUrl, it)
|
||||
}
|
||||
parent._links content
|
||||
}
|
||||
|
||||
private link(appUrl, type) {
|
||||
def result = [:]
|
||||
result.href = generateTemplatedUri(appUrl, type.action)
|
||||
result.templated = true
|
||||
result
|
||||
}
|
||||
|
||||
private generateTemplatedUri(appUrl, action) {
|
||||
String uri = appUrl != null ? appUrl + action : action
|
||||
UriTemplate uriTemplate = new UriTemplate(uri + '?style={dependencies}', this.templateVariables)
|
||||
uriTemplate.toString()
|
||||
}
|
||||
|
||||
|
||||
private static dependencies(parent, groups) {
|
||||
parent.dependencies {
|
||||
type 'hierarchical-multi-select'
|
||||
values groups.collect {
|
||||
processDependencyGroup(it)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static type(parent, defaultValue, dependencies) {
|
||||
parent.type {
|
||||
type 'action'
|
||||
if (defaultValue) {
|
||||
'default' defaultValue
|
||||
}
|
||||
values dependencies.collect {
|
||||
processType(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static singleSelect(parent, name, defaultValue, itemValues) {
|
||||
parent."$name" {
|
||||
type 'single-select'
|
||||
if (defaultValue) {
|
||||
'default' defaultValue
|
||||
}
|
||||
values itemValues.collect {
|
||||
processValue(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static text(parent, name, value) {
|
||||
parent."$name" {
|
||||
type 'text'
|
||||
if (value) {
|
||||
'default' value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static processDependencyGroup(group) {
|
||||
def result = [:]
|
||||
result.name = group.name
|
||||
if (group.hasProperty('description') && group.description) {
|
||||
result.description = group.description
|
||||
}
|
||||
def items = []
|
||||
group.content.collect {
|
||||
items << processValue(it)
|
||||
}
|
||||
result.values = items
|
||||
result
|
||||
}
|
||||
|
||||
private static processType(type) {
|
||||
def result = processValue(type)
|
||||
result.action = type.action
|
||||
result.tags = type.tags
|
||||
result
|
||||
}
|
||||
|
||||
private static processValue(value) {
|
||||
def result = [:]
|
||||
result.id = value.id
|
||||
result.name = value.name
|
||||
if (value.hasProperty('description') && value.description) {
|
||||
result.description = value.description
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
}
|
||||
@@ -29,6 +29,7 @@ import org.springframework.stereotype.Controller
|
||||
import org.springframework.web.bind.annotation.ModelAttribute
|
||||
import org.springframework.web.bind.annotation.RequestMapping
|
||||
import org.springframework.web.bind.annotation.ResponseBody
|
||||
import org.springframework.web.servlet.support.ServletUriComponentsBuilder
|
||||
|
||||
/**
|
||||
* The main initializr controller provides access to the configured
|
||||
@@ -53,12 +54,20 @@ class MainController extends AbstractInitializrController {
|
||||
request
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/")
|
||||
@RequestMapping(value = "/", headers = "user-agent=SpringBootCli/1.2.0.RC1")
|
||||
@ResponseBody
|
||||
InitializrMetadata metadata() {
|
||||
@Deprecated
|
||||
InitializrMetadata oldMetadata() {
|
||||
metadataProvider.get()
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/", produces = ["application/vnd.initializr.v2+json","application/json"])
|
||||
@ResponseBody
|
||||
String metadata() {
|
||||
String appUrl = ServletUriComponentsBuilder.fromCurrentServletMapping().build()
|
||||
metadataProvider.get().generateJson(appUrl)
|
||||
}
|
||||
|
||||
@RequestMapping(value = '/', produces = 'text/html')
|
||||
@ResponseBody
|
||||
String home() {
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 2012-2014 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 groovy.json.JsonSlurper
|
||||
import io.spring.initializr.support.InitializrMetadataBuilder
|
||||
import org.junit.Test
|
||||
|
||||
import static org.junit.Assert.assertEquals
|
||||
|
||||
/**
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
class InitializrMetadataJsonMapperTests {
|
||||
|
||||
private final InitializrMetadataJsonMapper jsonMapper = new InitializrMetadataJsonMapper()
|
||||
private final JsonSlurper slurper = new JsonSlurper()
|
||||
|
||||
@Test
|
||||
void withNoAppUrl() {
|
||||
InitializrMetadata metadata = new InitializrMetadataBuilder().addType('foo', true, '/foo.zip', 'none', 'test')
|
||||
.addDependencyGroup('foo', 'one', 'two').validateAndGet()
|
||||
def json = jsonMapper.write(metadata, null)
|
||||
def result = slurper.parseText(json)
|
||||
assertEquals '/foo.zip?style={dependencies}{&type,packaging,javaVersion,language,bootVersion,' +
|
||||
'groupId,artifactId,version,name,description,packageName}', result._links.foo.href
|
||||
}
|
||||
|
||||
@Test
|
||||
void withAppUrl() {
|
||||
InitializrMetadata metadata = new InitializrMetadataBuilder().addType('foo', true, '/foo.zip', 'none', 'test')
|
||||
.addDependencyGroup('foo', 'one', 'two').validateAndGet()
|
||||
def json = jsonMapper.write(metadata, 'http://server:8080/my-app')
|
||||
def result = slurper.parseText(json)
|
||||
assertEquals 'http://server:8080/my-app/foo.zip?style={dependencies}{&type,packaging,javaVersion,' +
|
||||
'language,bootVersion,groupId,artifactId,version,name,description,packageName}',
|
||||
result._links.foo.href
|
||||
}
|
||||
|
||||
}
|
||||
@@ -177,6 +177,13 @@ class InitializrMetadataTests {
|
||||
assertEquals metadata.defaults.groupId, request.groupId
|
||||
}
|
||||
|
||||
@Test
|
||||
void validateAction() {
|
||||
def metadata = new InitializrMetadataBuilder()
|
||||
.addType('foo', false, 'my-action.zip', 'none', 'none').validateAndGet()
|
||||
assertEquals '/my-action.zip', metadata.getType('foo').action
|
||||
}
|
||||
|
||||
@Test
|
||||
void validateArtifactRepository() {
|
||||
def metadata = InitializrMetadataBuilder.withDefaults().instance()
|
||||
|
||||
@@ -50,7 +50,7 @@ abstract class AbstractInitializrControllerIntegrationTests {
|
||||
public final TemporaryFolder folder = new TemporaryFolder()
|
||||
|
||||
@Value('${local.server.port}')
|
||||
private int port
|
||||
protected int port
|
||||
|
||||
final RestTemplate restTemplate = new RestTemplate()
|
||||
|
||||
|
||||
@@ -26,7 +26,11 @@ import org.skyscreamer.jsonassert.JSONAssert
|
||||
import org.skyscreamer.jsonassert.JSONCompareMode
|
||||
|
||||
import org.springframework.core.io.ClassPathResource
|
||||
import org.springframework.http.HttpEntity
|
||||
import org.springframework.http.HttpHeaders
|
||||
import org.springframework.http.HttpMethod
|
||||
import org.springframework.http.HttpStatus
|
||||
import org.springframework.http.MediaType
|
||||
import org.springframework.http.ResponseEntity
|
||||
import org.springframework.test.context.ActiveProfiles
|
||||
import org.springframework.util.StreamUtils
|
||||
@@ -40,8 +44,10 @@ import static org.junit.Assert.*
|
||||
@ActiveProfiles('test-default')
|
||||
class MainControllerIntegrationTests extends AbstractInitializrControllerIntegrationTests {
|
||||
|
||||
private final def slurper = new JsonSlurper()
|
||||
private static final MediaType CURRENT_METADATA_MEDIA_TYPE =
|
||||
MediaType.parseMediaType('application/vnd.initializr.v2+json')
|
||||
|
||||
private final def slurper = new JsonSlurper()
|
||||
|
||||
@Test
|
||||
void simpleZipProject() {
|
||||
@@ -104,25 +110,50 @@ class MainControllerIntegrationTests extends AbstractInitializrControllerIntegra
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void metadataWithNoAcceptHeader() { // rest template sets application/json by default
|
||||
ResponseEntity<String> response = getMetadata(null, '*/*')
|
||||
assertEquals CURRENT_METADATA_MEDIA_TYPE, response.getHeaders().getContentType()
|
||||
validateCurrentMetadata(new JSONObject(response.body))
|
||||
}
|
||||
|
||||
@Test
|
||||
void metadataWithCurrentAcceptHeader() {
|
||||
ResponseEntity<String> response = getMetadata(null, 'application/vnd.initializr.v2+json')
|
||||
assertEquals CURRENT_METADATA_MEDIA_TYPE, response.getHeaders().getContentType()
|
||||
validateCurrentMetadata(new JSONObject(response.body))
|
||||
}
|
||||
|
||||
@Test // Test that the current output is exactly what we expect
|
||||
void validateCurrentProjectMetadata() {
|
||||
def json = restTemplate.getForObject(createUrl('/'), String.class)
|
||||
def expected = readJson('1.1.0')
|
||||
JSONAssert.assertEquals(expected, new JSONObject(json), JSONCompareMode.STRICT)
|
||||
def json = getMetadataJson()
|
||||
validateCurrentMetadata(json)
|
||||
}
|
||||
|
||||
private void validateCurrentMetadata(JSONObject json) {
|
||||
def expected = readJson('2.0.0')
|
||||
JSONAssert.assertEquals(expected, json, JSONCompareMode.STRICT)
|
||||
}
|
||||
|
||||
@Test // Test that the current code complies exactly with 1.1.0
|
||||
void validateProjectMetadata110() {
|
||||
JSONObject json = getMetadataJson("SpringBootCli/1.2.0.RC1", null)
|
||||
def expected = readJson('1.0.1')
|
||||
JSONAssert.assertEquals(expected, json, JSONCompareMode.LENIENT)
|
||||
}
|
||||
|
||||
@Test // Test that the current code complies "at least" with 1.0.1
|
||||
void validateProjectMetadata101() {
|
||||
def json = restTemplate.getForObject(createUrl('/'), String.class)
|
||||
JSONObject json = getMetadataJson("SpringBootCli/1.2.0.RC1", null)
|
||||
def expected = readJson('1.0.1')
|
||||
JSONAssert.assertEquals(expected, new JSONObject(json), JSONCompareMode.LENIENT)
|
||||
JSONAssert.assertEquals(expected, json, JSONCompareMode.LENIENT)
|
||||
}
|
||||
|
||||
@Test // Test that the current code complies "at least" with 1.0.0
|
||||
void validateProjectMetadata100() {
|
||||
def json = restTemplate.getForObject(createUrl('/'), String.class)
|
||||
JSONObject json = getMetadataJson("SpringBootCli/1.2.0.RC1", null)
|
||||
def expected = readJson('1.0.0')
|
||||
JSONAssert.assertEquals(expected, new JSONObject(json), JSONCompareMode.LENIENT)
|
||||
JSONAssert.assertEquals(expected, json, JSONCompareMode.LENIENT)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -186,7 +217,7 @@ class MainControllerIntegrationTests extends AbstractInitializrControllerIntegra
|
||||
@Test
|
||||
void homeIsJson() {
|
||||
def body = restTemplate.getForObject(createUrl('/'), String)
|
||||
assertTrue("Wrong body:\n$body", body.contains('{"dependencies"'))
|
||||
assertTrue("Wrong body:\n$body", body.contains('"dependencies"'))
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -237,6 +268,27 @@ class MainControllerIntegrationTests extends AbstractInitializrControllerIntegra
|
||||
assertNotNull(response.body)
|
||||
}
|
||||
|
||||
private JSONObject getMetadataJson() {
|
||||
getMetadataJson(null, null)
|
||||
}
|
||||
|
||||
private JSONObject getMetadataJson(String userAgentHeader, String acceptHeader) {
|
||||
String json = getMetadata(userAgentHeader, acceptHeader).body
|
||||
return new JSONObject(json)
|
||||
}
|
||||
|
||||
private ResponseEntity<String> getMetadata(String userAgentHeader, String acceptHeader) {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
if (userAgentHeader) {
|
||||
headers.set("User-Agent", userAgentHeader);
|
||||
}
|
||||
if (acceptHeader) {
|
||||
headers.setAccept(Collections.singletonList(MediaType.parseMediaType(acceptHeader)))
|
||||
}
|
||||
return restTemplate.exchange(createUrl('/'),
|
||||
HttpMethod.GET, new HttpEntity<Void>(headers), String.class)
|
||||
}
|
||||
|
||||
|
||||
private byte[] invoke(String context) {
|
||||
restTemplate.getForObject(createUrl(context), byte[])
|
||||
@@ -252,12 +304,15 @@ class MainControllerIntegrationTests extends AbstractInitializrControllerIntegra
|
||||
tgzProjectAssert(body)
|
||||
}
|
||||
|
||||
private static JSONObject readJson(String version) {
|
||||
private JSONObject readJson(String version) {
|
||||
def resource = new ClassPathResource("metadata/test-default-$version" + ".json")
|
||||
def stream = resource.inputStream
|
||||
try {
|
||||
def json = StreamUtils.copyToString(stream, Charset.forName('UTF-8'))
|
||||
new JSONObject(json)
|
||||
|
||||
// Let's parse the port as it is random
|
||||
def content = json.replaceAll('@port@', String.valueOf(this.port))
|
||||
new JSONObject(content)
|
||||
} finally {
|
||||
stream.close()
|
||||
}
|
||||
|
||||
186
initializr/src/test/resources/metadata/test-default-2.0.0.json
Normal file
186
initializr/src/test/resources/metadata/test-default-2.0.0.json
Normal file
@@ -0,0 +1,186 @@
|
||||
{
|
||||
"_links": {
|
||||
"maven-build": {
|
||||
"href": "http://localhost:@port@/pom.xml?style={dependencies}{&type,packaging,javaVersion,language,bootVersion,groupId,artifactId,version,name,description,packageName}",
|
||||
"templated": true
|
||||
},
|
||||
"maven-project": {
|
||||
"href": "http://localhost:@port@/starter.zip?style={dependencies}{&type,packaging,javaVersion,language,bootVersion,groupId,artifactId,version,name,description,packageName}",
|
||||
"templated": true
|
||||
},
|
||||
"gradle-build": {
|
||||
"href": "http://localhost:@port@/build.gradle?style={dependencies}{&type,packaging,javaVersion,language,bootVersion,groupId,artifactId,version,name,description,packageName}",
|
||||
"templated": true
|
||||
},
|
||||
"gradle-project": {
|
||||
"href": "http://localhost:@port@/starter.zip?style={dependencies}{&type,packaging,javaVersion,language,bootVersion,groupId,artifactId,version,name,description,packageName}",
|
||||
"templated": true
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"type": "hierarchical-multi-select",
|
||||
"values": [
|
||||
{
|
||||
"name": "Core",
|
||||
"values": [
|
||||
{
|
||||
"id": "web",
|
||||
"name": "Web",
|
||||
"description": "Web dependency description"
|
||||
},
|
||||
{
|
||||
"id": "security",
|
||||
"name": "Security"
|
||||
},
|
||||
{
|
||||
"id": "data-jpa",
|
||||
"name": "Data JPA"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Other",
|
||||
"values": [
|
||||
{
|
||||
"id": "org.acme:foo",
|
||||
"name": "Foo"
|
||||
},
|
||||
{
|
||||
"id": "org.acme:bar",
|
||||
"name": "Bar"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"type": {
|
||||
"type": "action",
|
||||
"default": "maven-project",
|
||||
"values": [
|
||||
{
|
||||
"id": "maven-build",
|
||||
"name": "Maven POM",
|
||||
"action": "/pom.xml",
|
||||
"tags": {
|
||||
"build": "maven",
|
||||
"format": "build"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "maven-project",
|
||||
"name": "Maven Project",
|
||||
"action": "/starter.zip",
|
||||
"tags": {
|
||||
"build": "maven",
|
||||
"format": "project"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "gradle-build",
|
||||
"name": "Gradle Config",
|
||||
"action": "/build.gradle",
|
||||
"tags": {
|
||||
"build": "gradle",
|
||||
"format": "build"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "gradle-project",
|
||||
"name": "Gradle Project",
|
||||
"action": "/starter.zip",
|
||||
"tags": {
|
||||
"build": "gradle",
|
||||
"format": "project"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"packaging": {
|
||||
"type": "single-select",
|
||||
"default": "jar",
|
||||
"values": [
|
||||
{
|
||||
"id": "jar",
|
||||
"name": "Jar"
|
||||
},
|
||||
{
|
||||
"id": "war",
|
||||
"name": "War"
|
||||
}
|
||||
]
|
||||
},
|
||||
"javaVersion": {
|
||||
"type": "single-select",
|
||||
"default": "1.7",
|
||||
"values": [
|
||||
{
|
||||
"id": "1.6",
|
||||
"name": "1.6"
|
||||
},
|
||||
{
|
||||
"id": "1.7",
|
||||
"name": "1.7"
|
||||
},
|
||||
{
|
||||
"id": "1.8",
|
||||
"name": "1.8"
|
||||
}
|
||||
]
|
||||
},
|
||||
"language": {
|
||||
"type": "single-select",
|
||||
"default": "java",
|
||||
"values": [
|
||||
{
|
||||
"id": "groovy",
|
||||
"name": "Groovy"
|
||||
},
|
||||
{
|
||||
"id": "java",
|
||||
"name": "Java"
|
||||
}
|
||||
]
|
||||
},
|
||||
"bootVersion": {
|
||||
"type": "single-select",
|
||||
"default": "1.1.4.RELEASE",
|
||||
"values": [
|
||||
{
|
||||
"id": "1.2.0.BUILD-SNAPSHOT",
|
||||
"name": "Latest SNAPSHOT"
|
||||
},
|
||||
{
|
||||
"id": "1.1.4.RELEASE",
|
||||
"name": "1.1.4"
|
||||
},
|
||||
{
|
||||
"id": "1.0.2.RELEASE",
|
||||
"name": "1.0.2"
|
||||
}
|
||||
]
|
||||
},
|
||||
"groupId": {
|
||||
"type": "text",
|
||||
"default": "org.test"
|
||||
},
|
||||
"artifactId": {
|
||||
"type": "text",
|
||||
"default": "demo"
|
||||
},
|
||||
"version": {
|
||||
"type": "text",
|
||||
"default": "0.0.1-SNAPSHOT"
|
||||
},
|
||||
"name": {
|
||||
"type": "text",
|
||||
"default": "demo"
|
||||
},
|
||||
"description": {
|
||||
"type": "text",
|
||||
"default": "Demo project for Spring Boot"
|
||||
},
|
||||
"packageName": {
|
||||
"type": "text",
|
||||
"default": "demo"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user