diff --git a/initializr/src/main/groovy/io/spring/initializr/config/InitializrAutoConfiguration.groovy b/initializr/src/main/groovy/io/spring/initializr/config/InitializrAutoConfiguration.groovy index ea9178be..02b80499 100644 --- a/initializr/src/main/groovy/io/spring/initializr/config/InitializrAutoConfiguration.groovy +++ b/initializr/src/main/groovy/io/spring/initializr/config/InitializrAutoConfiguration.groovy @@ -28,6 +28,7 @@ import io.spring.initializr.metadata.InitializrMetadataProvider import io.spring.initializr.metadata.InitializrProperties import io.spring.initializr.support.DefaultInitializrMetadataProvider import io.spring.initializr.web.MainController +import io.spring.initializr.web.UiController import io.spring.initializr.web.WebConfig import org.springframework.beans.factory.annotation.Autowired @@ -72,6 +73,12 @@ class InitializrAutoConfiguration { new MainController() } + @Bean + @ConditionalOnMissingBean(UiController) + UiController initializrUiController() { + new UiController() + } + @Bean @ConditionalOnMissingBean(ProjectGenerator) ProjectGenerator projectGenerator() { diff --git a/initializr/src/main/groovy/io/spring/initializr/web/MainController.groovy b/initializr/src/main/groovy/io/spring/initializr/web/MainController.groovy index 025e4c93..5f69657d 100644 --- a/initializr/src/main/groovy/io/spring/initializr/web/MainController.groovy +++ b/initializr/src/main/groovy/io/spring/initializr/web/MainController.groovy @@ -24,7 +24,6 @@ import io.spring.initializr.mapper.InitializrMetadataV2JsonMapper import io.spring.initializr.mapper.InitializrMetadataVersion import io.spring.initializr.generator.ProjectGenerator import io.spring.initializr.generator.ProjectRequest -import io.spring.initializr.metadata.Dependency import io.spring.initializr.metadata.InitializrMetadata import org.springframework.beans.factory.annotation.Autowired @@ -126,12 +125,6 @@ class MainController extends AbstractInitializrController { renderHome('home.html') } - @RequestMapping(value = '/dependencies.json', produces = 'application/json') - @ResponseBody - List dependencies() { - metadataProvider.get().dependencies.content.collectMany {it.content} - } - @RequestMapping('/spring') String spring() { def url = metadataProvider.get().createCliDistributionURl('zip') diff --git a/initializr/src/main/groovy/io/spring/initializr/web/UiController.groovy b/initializr/src/main/groovy/io/spring/initializr/web/UiController.groovy new file mode 100644 index 00000000..deee706c --- /dev/null +++ b/initializr/src/main/groovy/io/spring/initializr/web/UiController.groovy @@ -0,0 +1,79 @@ +/* + * Copyright 2012-2015 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.spring.initializr.web + +import groovy.json.JsonBuilder +import io.spring.initializr.metadata.DependenciesCapability +import io.spring.initializr.metadata.Dependency +import io.spring.initializr.metadata.InitializrMetadataProvider +import io.spring.initializr.util.Version +import io.spring.initializr.util.VersionRange + +import org.springframework.beans.factory.annotation.Autowired +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 + * @since 1.0 + */ +@RestController +class UiController { + + @Autowired + protected InitializrMetadataProvider metadataProvider + + @RequestMapping(value = "/ui/dependencies" , produces = ["application/json"]) + String dependencies(@RequestParam(required = false) String version) { + DependenciesCapability dependenciesCapability = metadataProvider.get().dependencies + List allDependencies = dependenciesCapability.content.collectMany { it.content } + if (version) { + Version v = Version.parse(version) + def filteredDependencies = allDependencies.findAll { d -> + if (d.versionRange) { + return VersionRange.parse(d.versionRange).match(v) + } + return true + } + writeDependencies(filteredDependencies) + } else { + writeDependencies(allDependencies) + } + } + + private static String writeDependencies(List deps) { + JsonBuilder json = new JsonBuilder(); + json { + dependencies deps.collect { d -> + mapDependency(d) + } + } + json.toString() + } + + private static mapDependency(Dependency d) { + def result = [:] + result.id = d.id + result.name = d.name + result.description = d.description + result + } + +} diff --git a/initializr/src/main/resources/static/js/start.js b/initializr/src/main/resources/static/js/start.js index f8dbdcce..4f8dfcfc 100644 --- a/initializr/src/main/resources/static/js/start.js +++ b/initializr/src/main/resources/static/js/start.js @@ -92,9 +92,9 @@ $(function () { $("#starters div[data-id='" + id + "']").remove(); }; var initializeSearchEngine = function (engine, bootVersion) { - $.getJSON("/dependencies.json?version=" + bootVersion, function (data) { + $.getJSON("/ui/dependencies.json?version=" + bootVersion, function (data) { engine.clear(); - engine.add(data); + engine.add(data.dependencies); }); }; refreshDependencies($("#bootVersion").val()); diff --git a/initializr/src/test/groovy/io/spring/initializr/web/UiControllerIntegrationTests.groovy b/initializr/src/test/groovy/io/spring/initializr/web/UiControllerIntegrationTests.groovy new file mode 100644 index 00000000..312b30f5 --- /dev/null +++ b/initializr/src/test/groovy/io/spring/initializr/web/UiControllerIntegrationTests.groovy @@ -0,0 +1,53 @@ +/* + * Copyright 2012-2015 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.spring.initializr.web + +import org.json.JSONObject +import org.junit.Test +import org.skyscreamer.jsonassert.JSONAssert +import org.skyscreamer.jsonassert.JSONCompareMode + +import org.springframework.http.MediaType +import org.springframework.http.ResponseEntity +import org.springframework.test.context.ActiveProfiles + +/** + * @author Stephane Nicoll + */ +@ActiveProfiles('test-default') +class UiControllerIntegrationTests extends AbstractInitializrControllerIntegrationTests { + + @Test + void dependenciesNoVersion() { + ResponseEntity response = execute('/ui/dependencies', String, null, null) + validateContentType(response, MediaType.APPLICATION_JSON) + validateDependenciesOutput('all', new JSONObject(response.body)) + } + + @Test + void dependenciesSpecificVersion() { + ResponseEntity response = execute('/ui/dependencies?version=1.1.2.RELEASE', String, null, null) + validateContentType(response, MediaType.APPLICATION_JSON) + validateDependenciesOutput('1.1.2', new JSONObject(response.body)) + } + + protected void validateDependenciesOutput(String version, JSONObject actual) { + def expected = readJsonFrom("metadata/dependencies/test-dependencies-$version" + ".json") + JSONAssert.assertEquals(expected, actual, JSONCompareMode.STRICT) + } + +} diff --git a/initializr/src/test/resources/metadata/dependencies/test-dependencies-1.1.2.json b/initializr/src/test/resources/metadata/dependencies/test-dependencies-1.1.2.json new file mode 100644 index 00000000..1954cd49 --- /dev/null +++ b/initializr/src/test/resources/metadata/dependencies/test-dependencies-1.1.2.json @@ -0,0 +1,34 @@ +{ + "dependencies": [ + { + "id": "web", + "name": "Web", + "description": "Web dependency description" + }, + { + "id": "security", + "name": "Security", + "description": null + }, + { + "id": "data-jpa", + "name": "Data JPA", + "description": null + }, + { + "id": "org.acme:foo", + "name": "Foo", + "description": null + }, + { + "id": "org.acme:bar", + "name": "Bar", + "description": null + }, + { + "id": "my-api", + "name": "My API", + "description": null + } + ] +} diff --git a/initializr/src/test/resources/metadata/dependencies/test-dependencies-all.json b/initializr/src/test/resources/metadata/dependencies/test-dependencies-all.json new file mode 100644 index 00000000..c163180f --- /dev/null +++ b/initializr/src/test/resources/metadata/dependencies/test-dependencies-all.json @@ -0,0 +1,44 @@ +{ + "dependencies": [ + { + "id": "web", + "name": "Web", + "description": "Web dependency description" + }, + { + "id": "security", + "name": "Security", + "description": null + }, + { + "id": "data-jpa", + "name": "Data JPA", + "description": null + }, + { + "id": "org.acme:foo", + "name": "Foo", + "description": null + }, + { + "id": "org.acme:bar", + "name": "Bar", + "description": null + }, + { + "id": "org.acme:biz", + "name": "Biz", + "description": null + }, + { + "id": "org.acme:bur", + "name": "Bur", + "description": null + }, + { + "id": "my-api", + "name": "My API", + "description": null + } + ] +}