Remove use of org.json

This commit removes all use of org.json in production code and moves
the json api to a test only dependency.

Closes gh-507
This commit is contained in:
Stephane Nicoll 2017-12-29 13:29:28 +01:00
parent 8e5b910af6
commit 63becddb94
23 changed files with 353 additions and 260 deletions

View File

@ -16,8 +16,8 @@
package io.spring.initializr.actuate; package io.spring.initializr.actuate;
import com.fasterxml.jackson.databind.JsonNode;
import io.spring.initializr.web.AbstractFullStackInitializrIntegrationTests; import io.spring.initializr.web.AbstractFullStackInitializrIntegrationTests;
import org.json.JSONObject;
import org.junit.Test; import org.junit.Test;
import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.ActiveProfiles;
@ -45,35 +45,32 @@ public class ActuatorIntegrationTests
@Test @Test
public void metricsAvailableByDefault() { public void metricsAvailableByDefault() {
downloadZip("/starter.zip?packaging=jar&javaVersion=1.8&style=web&style=jpa"); downloadZip("/starter.zip?packaging=jar&javaVersion=1.8&style=web&style=jpa");
JSONObject result = metricsEndpoint(); JsonNode result = metricsEndpoint();
int requests = result.getInt("counter.initializr.requests"); int requests = result.get("counter.initializr.requests").intValue();
int packaging = result.getInt("counter.initializr.packaging.jar"); int packaging = result.get("counter.initializr.packaging.jar").intValue();
int javaVersion = result.getInt("counter.initializr.java_version.1_8"); int javaVersion = result.get("counter.initializr.java_version.1_8").intValue();
int webDependency = result.getInt("counter.initializr.dependency.web"); int webDependency = result.get("counter.initializr.dependency.web").intValue();
int jpaDependency = result.getInt("counter.initializr.dependency.data-jpa"); int jpaDependency = result.get("counter.initializr.dependency.data-jpa")
.intValue();
// No jpa dep this time // No jpa dep this time
downloadZip("/starter.zip?packaging=jar&javaVersion=1.8&style=web"); downloadZip("/starter.zip?packaging=jar&javaVersion=1.8&style=web");
JSONObject updatedResult = metricsEndpoint(); JsonNode updatedResult = metricsEndpoint();
assertEquals("Number of request should have increased", requests + 1, assertEquals("Number of request should have increased", requests + 1,
updatedResult.getInt("counter.initializr.requests")); updatedResult.get("counter.initializr.requests").intValue());
assertEquals("jar packaging metric should have increased", packaging + 1, assertEquals("jar packaging metric should have increased", packaging + 1,
updatedResult.getInt("counter.initializr.packaging.jar")); updatedResult.get("counter.initializr.packaging.jar").intValue());
assertEquals("java version metric should have increased", javaVersion + 1, assertEquals("java version metric should have increased", javaVersion + 1,
updatedResult.getInt("counter.initializr.java_version.1_8")); updatedResult.get("counter.initializr.java_version.1_8").intValue());
assertEquals("web dependency metric should have increased", webDependency + 1, assertEquals("web dependency metric should have increased", webDependency + 1,
updatedResult.getInt("counter.initializr.dependency.web")); updatedResult.get("counter.initializr.dependency.web").intValue());
assertEquals("jpa dependency metric should not have increased", jpaDependency, assertEquals("jpa dependency metric should not have increased", jpaDependency,
updatedResult.getInt("counter.initializr.dependency.data-jpa")); updatedResult.get("counter.initializr.dependency.data-jpa").intValue());
} }
private JSONObject metricsEndpoint() { private JsonNode metricsEndpoint() {
return parseJson(getRestTemplate().getForObject(createUrl("/metrics"), String.class)); return parseJson(getRestTemplate().getForObject(createUrl("/metrics"), String.class));
} }
private JSONObject parseJson(String content) {
return new JSONObject(content);
}
} }

View File

@ -20,10 +20,9 @@ import java.net.URI;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import com.fasterxml.jackson.databind.JsonNode;
import io.spring.initializr.actuate.stat.MainControllerStatsIntegrationTests.StatsMockController; import io.spring.initializr.actuate.stat.MainControllerStatsIntegrationTests.StatsMockController;
import io.spring.initializr.web.AbstractFullStackInitializrIntegrationTests; import io.spring.initializr.web.AbstractFullStackInitializrIntegrationTests;
import org.json.JSONArray;
import org.json.JSONObject;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
@ -74,12 +73,12 @@ public class MainControllerStatsIntegrationTests
assertEquals("No stat got generated", 1, statsMockController.stats.size()); assertEquals("No stat got generated", 1, statsMockController.stats.size());
StatsMockController.Content content = statsMockController.stats.get(0); StatsMockController.Content content = statsMockController.stats.get(0);
JSONObject json = new JSONObject(content.json); JsonNode json = parseJson(content.json);
assertEquals("com.foo", json.get("groupId")); assertEquals("com.foo", json.get("groupId").textValue());
assertEquals("bar", json.get("artifactId")); assertEquals("bar", json.get("artifactId").textValue());
JSONArray list = json.getJSONArray("dependencies"); JsonNode list = json.get("dependencies");
assertEquals(1, list.length()); assertEquals(1, list.size());
assertEquals("web", list.get(0)); assertEquals("web", list.get(0).textValue());
} }
@Test @Test
@ -104,7 +103,7 @@ public class MainControllerStatsIntegrationTests
assertEquals("No stat got generated", 1, statsMockController.stats.size()); assertEquals("No stat got generated", 1, statsMockController.stats.size());
StatsMockController.Content content = statsMockController.stats.get(0); StatsMockController.Content content = statsMockController.stats.get(0);
JSONObject json = new JSONObject(content.json); JsonNode json = parseJson(content.json);
assertFalse("requestIp property should not be set", json.has("requestIp")); assertFalse("requestIp property should not be set", json.has("requestIp"));
} }
@ -116,8 +115,8 @@ public class MainControllerStatsIntegrationTests
assertEquals("No stat got generated", 1, statsMockController.stats.size()); assertEquals("No stat got generated", 1, statsMockController.stats.size());
StatsMockController.Content content = statsMockController.stats.get(0); StatsMockController.Content content = statsMockController.stats.get(0);
JSONObject json = new JSONObject(content.json); JsonNode json = parseJson(content.json);
assertEquals("Wrong requestIp", "10.0.0.123", json.get("requestIp")); assertEquals("Wrong requestIp", "10.0.0.123", json.get("requestIp").textValue());
} }
@Test @Test
@ -128,7 +127,7 @@ public class MainControllerStatsIntegrationTests
assertEquals("No stat got generated", 1, statsMockController.stats.size()); assertEquals("No stat got generated", 1, statsMockController.stats.size());
StatsMockController.Content content = statsMockController.stats.get(0); StatsMockController.Content content = statsMockController.stats.get(0);
JSONObject json = new JSONObject(content.json); JsonNode json = parseJson(content.json);
assertFalse("requestIpv4 property should not be set if value is not a valid IPv4", assertFalse("requestIpv4 property should not be set if value is not a valid IPv4",
json.has("requestIpv4")); json.has("requestIpv4"));
} }
@ -141,7 +140,7 @@ public class MainControllerStatsIntegrationTests
assertEquals("No stat got generated", 1, statsMockController.stats.size()); assertEquals("No stat got generated", 1, statsMockController.stats.size());
StatsMockController.Content content = statsMockController.stats.get(0); StatsMockController.Content content = statsMockController.stats.get(0);
JSONObject json = new JSONObject(content.json); JsonNode json = parseJson(content.json);
assertFalse("requestCountry property should not be set if value is set to xx", assertFalse("requestCountry property should not be set if value is set to xx",
json.has("requestCountry")); json.has("requestCountry"));
} }
@ -158,13 +157,13 @@ public class MainControllerStatsIntegrationTests
assertEquals("No stat got generated", 1, statsMockController.stats.size()); assertEquals("No stat got generated", 1, statsMockController.stats.size());
StatsMockController.Content content = statsMockController.stats.get(0); StatsMockController.Content content = statsMockController.stats.get(0);
JSONObject json = new JSONObject(content.json); JsonNode json = parseJson(content.json);
assertEquals("com.example", json.get("groupId")); assertEquals("com.example", json.get("groupId").textValue());
assertEquals("demo", json.get("artifactId")); assertEquals("demo", json.get("artifactId").textValue());
assertEquals(true, json.get("invalid")); assertEquals(true, json.get("invalid").booleanValue());
assertEquals(true, json.get("invalidType")); assertEquals(true, json.get("invalidType").booleanValue());
assertNotNull(json.get("errorMessage")); assertNotNull(json.get("errorMessage"));
assertTrue(((String) json.get("errorMessage")).contains("invalid-type")); assertTrue(json.get("errorMessage").textValue().contains("invalid-type"));
} }
@Test @Test

View File

@ -16,13 +16,14 @@
package io.spring.initializr.service; package io.spring.initializr.service;
import java.io.IOException;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.spring.initializr.metadata.InitializrMetadata; import io.spring.initializr.metadata.InitializrMetadata;
import io.spring.initializr.metadata.InitializrMetadataBuilder; import io.spring.initializr.metadata.InitializrMetadataBuilder;
import io.spring.initializr.metadata.InitializrMetadataProvider; import io.spring.initializr.metadata.InitializrMetadataProvider;
import org.json.JSONObject;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
@ -55,13 +56,13 @@ public class InitializrServiceSmokeTests {
private InitializrMetadataProvider metadataProvider; private InitializrMetadataProvider metadataProvider;
@Test @Test
public void metadataCanBeSerialized() throws URISyntaxException { public void metadataCanBeSerialized() throws URISyntaxException, IOException {
RequestEntity<Void> request = RequestEntity.get(new URI("/")) RequestEntity<Void> request = RequestEntity.get(new URI("/"))
.accept(MediaType.parseMediaType("application/vnd.initializr.v2.1+json")) .accept(MediaType.parseMediaType("application/vnd.initializr.v2.1+json"))
.build(); .build();
ResponseEntity<String> response = this.restTemplate.exchange(request, String.class); ResponseEntity<String> response = this.restTemplate.exchange(request, String.class);
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
new JSONObject(response.getBody()); new ObjectMapper().readTree(response.getBody());
} }
@Test @Test

View File

@ -36,10 +36,6 @@
<groupId>org.apache.ant</groupId> <groupId>org.apache.ant</groupId>
<artifactId>ant</artifactId> <artifactId>ant</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
</dependency>
<dependency> <dependency>
<groupId>javax.cache</groupId> <groupId>javax.cache</groupId>
@ -79,6 +75,11 @@
<artifactId>spring-restdocs-mockmvc</artifactId> <artifactId>spring-restdocs-mockmvc</artifactId>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>com.vaadin.external.google</groupId>
<artifactId>android-json</artifactId>
<scope>test</scope>
</dependency>
<dependency> <dependency>
<groupId>xmlunit</groupId> <groupId>xmlunit</groupId>
<artifactId>xmlunit</artifactId> <artifactId>xmlunit</artifactId>

View File

@ -23,6 +23,7 @@ import javax.cache.configuration.MutableConfiguration;
import javax.cache.expiry.CreatedExpiryPolicy; import javax.cache.expiry.CreatedExpiryPolicy;
import javax.cache.expiry.Duration; import javax.cache.expiry.Duration;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.spring.initializr.generator.ProjectGenerator; import io.spring.initializr.generator.ProjectGenerator;
import io.spring.initializr.generator.ProjectRequestPostProcessor; import io.spring.initializr.generator.ProjectRequestPostProcessor;
import io.spring.initializr.generator.ProjectRequestResolver; import io.spring.initializr.generator.ProjectRequestResolver;
@ -45,6 +46,7 @@ import org.springframework.boot.autoconfigure.cache.JCacheManagerCustomizer;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
import org.springframework.boot.autoconfigure.web.WebClientAutoConfiguration; import org.springframework.boot.autoconfigure.web.WebClientAutoConfiguration;
import org.springframework.boot.bind.RelaxedPropertyResolver; import org.springframework.boot.bind.RelaxedPropertyResolver;
import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties;
@ -67,7 +69,8 @@ import org.springframework.web.servlet.resource.ResourceUrlProvider;
*/ */
@Configuration @Configuration
@EnableConfigurationProperties(InitializrProperties.class) @EnableConfigurationProperties(InitializrProperties.class)
@AutoConfigureAfter({ CacheAutoConfiguration.class, WebClientAutoConfiguration.class }) @AutoConfigureAfter({ CacheAutoConfiguration.class, JacksonAutoConfiguration.class,
WebClientAutoConfiguration.class })
public class InitializrAutoConfiguration { public class InitializrAutoConfiguration {
private final List<ProjectRequestPostProcessor> postProcessors; private final List<ProjectRequestPostProcessor> postProcessors;
@ -110,11 +113,12 @@ public class InitializrAutoConfiguration {
@ConditionalOnMissingBean(InitializrMetadataProvider.class) @ConditionalOnMissingBean(InitializrMetadataProvider.class)
public InitializrMetadataProvider initializrMetadataProvider( public InitializrMetadataProvider initializrMetadataProvider(
InitializrProperties properties, InitializrProperties properties,
ObjectMapper objectMapper,
RestTemplateBuilder restTemplateBuilder) { RestTemplateBuilder restTemplateBuilder) {
InitializrMetadata metadata = InitializrMetadataBuilder InitializrMetadata metadata = InitializrMetadataBuilder
.fromInitializrProperties(properties).build(); .fromInitializrProperties(properties).build();
return new DefaultInitializrMetadataProvider(metadata, return new DefaultInitializrMetadataProvider(metadata,
restTemplateBuilder.build()); objectMapper, restTemplateBuilder.build());
} }
@Bean @Bean

View File

@ -16,15 +16,17 @@
package io.spring.initializr.web.mapper; package io.spring.initializr.web.mapper;
import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
import io.spring.initializr.metadata.BillOfMaterials; import io.spring.initializr.metadata.BillOfMaterials;
import io.spring.initializr.metadata.Dependency; import io.spring.initializr.metadata.Dependency;
import io.spring.initializr.metadata.DependencyMetadata; import io.spring.initializr.metadata.DependencyMetadata;
import io.spring.initializr.metadata.Repository; import io.spring.initializr.metadata.Repository;
import org.json.JSONObject;
/** /**
* A {@link DependencyMetadataJsonMapper} handling the metadata format for v2.1. * A {@link DependencyMetadataJsonMapper} handling the metadata format for v2.1.
@ -33,59 +35,70 @@ import org.json.JSONObject;
*/ */
public class DependencyMetadataV21JsonMapper implements DependencyMetadataJsonMapper { public class DependencyMetadataV21JsonMapper implements DependencyMetadataJsonMapper {
private static final JsonNodeFactory nodeFactory = JsonNodeFactory.instance;
@Override @Override
public String write(DependencyMetadata metadata) { public String write(DependencyMetadata metadata) {
JSONObject json = new JSONObject(); ObjectNode json = nodeFactory.objectNode();
json.put("bootVersion", metadata.getBootVersion().toString()); json.put("bootVersion", metadata.getBootVersion().toString());
json.put("dependencies", json.set("dependencies",
metadata.getDependencies().entrySet().stream() mapNode(metadata.getDependencies().entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getKey, .collect(Collectors.toMap(Map.Entry::getKey,
entry -> mapDependency(entry.getValue())))); entry -> mapDependency(entry.getValue())))));
json.put("repositories", json.set("repositories",
metadata.getRepositories().entrySet().stream() mapNode(metadata.getRepositories().entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getKey, .collect(Collectors.toMap(Map.Entry::getKey,
entry -> mapRepository(entry.getValue())))); entry -> mapRepository(entry.getValue())))));
json.put("boms", metadata.getBoms().entrySet().stream().collect(Collectors json.set("boms",
.toMap(Map.Entry::getKey, entry -> mapBom(entry.getValue())))); mapNode(metadata.getBoms().entrySet().stream().collect(Collectors
.toMap(Map.Entry::getKey, entry -> mapBom(entry.getValue())))));
return json.toString(); return json.toString();
} }
private static Map<String, Object> mapDependency(Dependency dep) { private static JsonNode mapDependency(Dependency dep) {
Map<String, Object> result = new LinkedHashMap<>(); ObjectNode node = nodeFactory.objectNode();
result.put("groupId", dep.getGroupId()); node.put("groupId", dep.getGroupId());
result.put("artifactId", dep.getArtifactId()); node.put("artifactId", dep.getArtifactId());
if (dep.getVersion() != null) { if (dep.getVersion() != null) {
result.put("version", dep.getVersion()); node.put("version", dep.getVersion());
} }
result.put("scope", dep.getScope()); node.put("scope", dep.getScope());
if (dep.getBom() != null) { if (dep.getBom() != null) {
result.put("bom", dep.getBom()); node.put("bom", dep.getBom());
} }
if (dep.getRepository() != null) { if (dep.getRepository() != null) {
result.put("repository", dep.getRepository()); node.put("repository", dep.getRepository());
} }
return result; return node;
} }
private static Map<String, Object> mapRepository(Repository repo) { private static JsonNode mapRepository(Repository repo) {
Map<String, Object> result = new LinkedHashMap<>(); ObjectNode node = nodeFactory.objectNode();
result.put("name", repo.getName()); node.put("name", repo.getName())
result.put("url", repo.getUrl()); .put("url", (repo.getUrl() != null ? repo.getUrl().toString() : null))
result.put("snapshotEnabled", repo.isSnapshotsEnabled()); .put("snapshotEnabled", repo.isSnapshotsEnabled());
return result; return node;
} }
private static Map<String, Object> mapBom(BillOfMaterials bom) { private static JsonNode mapBom(BillOfMaterials bom) {
Map<String, Object> result = new LinkedHashMap<>(); ObjectNode node = nodeFactory.objectNode();
result.put("groupId", bom.getGroupId()); node.put("groupId", bom.getGroupId());
result.put("artifactId", bom.getArtifactId()); node.put("artifactId", bom.getArtifactId());
if (bom.getVersion() != null) { if (bom.getVersion() != null) {
result.put("version", bom.getVersion()); node.put("version", bom.getVersion());
} }
if (bom.getRepositories() != null) { if (bom.getRepositories() != null) {
result.put("repositories", bom.getRepositories()); ArrayNode array = nodeFactory.arrayNode();
bom.getRepositories().forEach(array::add);
node.set("repositories", array);
} }
return result; return node;
}
private static JsonNode mapNode(Map<String, JsonNode> content) {
ObjectNode node = nodeFactory.objectNode();
content.forEach(node::set);
return node;
} }
} }

View File

@ -16,13 +16,11 @@
package io.spring.initializr.web.mapper; package io.spring.initializr.web.mapper;
import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import com.fasterxml.jackson.databind.node.ObjectNode;
import io.spring.initializr.metadata.Dependency; import io.spring.initializr.metadata.Dependency;
import io.spring.initializr.metadata.Type; import io.spring.initializr.metadata.Type;
import org.json.JSONObject;
import org.springframework.hateoas.TemplateVariable; import org.springframework.hateoas.TemplateVariable;
import org.springframework.hateoas.TemplateVariables; import org.springframework.hateoas.TemplateVariables;
@ -49,30 +47,29 @@ public class InitializrMetadataV21JsonMapper extends InitializrMetadataV2JsonMap
} }
@Override @Override
protected Map<String, Object> links(JSONObject parent, List<Type> types, protected ObjectNode links(ObjectNode parent, List<Type> types, String appUrl) {
String appUrl) { ObjectNode links = super.links(parent, types, appUrl);
Map<String, Object> links = super.links(parent, types, appUrl); links.set("dependencies", dependenciesLink(appUrl));
links.put("dependencies", dependenciesLink(appUrl)); parent.set("_links", links);
parent.put("_links", links);
return links; return links;
} }
@Override @Override
protected Map<String, Object> mapDependency(Dependency dependency) { protected ObjectNode mapDependency(Dependency dependency) {
Map<String, Object> content = mapValue(dependency); ObjectNode content = mapValue(dependency);
if (dependency.getVersionRange() != null) { if (dependency.getVersionRange() != null) {
content.put("versionRange", dependency.getVersionRange()); content.put("versionRange", dependency.getVersionRange());
} }
if (dependency.getLinks() != null && !dependency.getLinks().isEmpty()) { if (dependency.getLinks() != null && !dependency.getLinks().isEmpty()) {
content.put("_links", LinkMapper.mapLinks(dependency.getLinks())); content.set("_links", LinkMapper.mapLinks(dependency.getLinks()));
} }
return content; return content;
} }
private Map<String, Object> dependenciesLink(String appUrl) { private ObjectNode dependenciesLink(String appUrl) {
String uri = appUrl != null ? appUrl + "/dependencies" : "/dependencies"; String uri = appUrl != null ? appUrl + "/dependencies" : "/dependencies";
UriTemplate uriTemplate = new UriTemplate(uri, this.dependenciesVariables); UriTemplate uriTemplate = new UriTemplate(uri, this.dependenciesVariables);
Map<String, Object> result = new LinkedHashMap<>(); ObjectNode result = nodeFactory().objectNode();
result.put("href", uriTemplate.toString()); result.put("href", uriTemplate.toString());
result.put("templated", true); result.put("templated", true);
return result; return result;

View File

@ -16,12 +16,13 @@
package io.spring.initializr.web.mapper; package io.spring.initializr.web.mapper;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
import io.spring.initializr.metadata.DefaultMetadataElement; import io.spring.initializr.metadata.DefaultMetadataElement;
import io.spring.initializr.metadata.DependenciesCapability; import io.spring.initializr.metadata.DependenciesCapability;
import io.spring.initializr.metadata.Dependency; import io.spring.initializr.metadata.Dependency;
@ -33,7 +34,6 @@ import io.spring.initializr.metadata.SingleSelectCapability;
import io.spring.initializr.metadata.TextCapability; import io.spring.initializr.metadata.TextCapability;
import io.spring.initializr.metadata.Type; import io.spring.initializr.metadata.Type;
import io.spring.initializr.metadata.TypeCapability; import io.spring.initializr.metadata.TypeCapability;
import org.json.JSONObject;
import org.springframework.hateoas.TemplateVariable; import org.springframework.hateoas.TemplateVariable;
import org.springframework.hateoas.TemplateVariables; import org.springframework.hateoas.TemplateVariables;
@ -47,6 +47,8 @@ import org.springframework.util.StringUtils;
*/ */
public class InitializrMetadataV2JsonMapper implements InitializrMetadataJsonMapper { public class InitializrMetadataV2JsonMapper implements InitializrMetadataJsonMapper {
private static final JsonNodeFactory nodeFactory = JsonNodeFactory.instance;
private final TemplateVariables templateVariables; private final TemplateVariables templateVariables;
public InitializrMetadataV2JsonMapper() { public InitializrMetadataV2JsonMapper() {
@ -74,9 +76,13 @@ public class InitializrMetadataV2JsonMapper implements InitializrMetadataJsonMap
TemplateVariable.VariableType.REQUEST_PARAM)); TemplateVariable.VariableType.REQUEST_PARAM));
} }
protected JsonNodeFactory nodeFactory() {
return nodeFactory;
}
@Override @Override
public String write(InitializrMetadata metadata, String appUrl) { public String write(InitializrMetadata metadata, String appUrl) {
JSONObject delegate = new JSONObject(); ObjectNode delegate = nodeFactory.objectNode();
links(delegate, metadata.getTypes().getContent(), appUrl); links(delegate, metadata.getTypes().getContent(), appUrl);
dependencies(delegate, metadata.getDependencies()); dependencies(delegate, metadata.getDependencies());
type(delegate, metadata.getTypes()); type(delegate, metadata.getTypes());
@ -93,15 +99,15 @@ public class InitializrMetadataV2JsonMapper implements InitializrMetadataJsonMap
return delegate.toString(); return delegate.toString();
} }
protected Map<String, Object> links(JSONObject parent, List<Type> types, String appUrl) { protected ObjectNode links(ObjectNode parent, List<Type> types, String appUrl) {
Map<String, Object> content = new LinkedHashMap<>(); ObjectNode content = nodeFactory.objectNode();
types.forEach(it -> content.put(it.getId(), link(appUrl, it))); types.forEach(it -> content.set(it.getId(), link(appUrl, it)));
parent.put("_links", content); parent.set("_links", content);
return content; return content;
} }
protected Map<String, Object> link(String appUrl, Type type) { protected ObjectNode link(String appUrl, Type type) {
Map<String, Object> result = new LinkedHashMap<>(); ObjectNode result = nodeFactory.objectNode();
result.put("href", generateTemplatedUri(appUrl, type)); result.put("href", generateTemplatedUri(appUrl, type));
result.put("templated", true); result.put("templated", true);
return result; return result;
@ -114,68 +120,73 @@ public class InitializrMetadataV2JsonMapper implements InitializrMetadataJsonMap
return uriTemplate.toString(); return uriTemplate.toString();
} }
protected void dependencies(JSONObject parent, DependenciesCapability capability) { protected void dependencies(ObjectNode parent, DependenciesCapability capability) {
Map<String, Object> map = new LinkedHashMap<>(); ObjectNode dependencies = nodeFactory.objectNode();
map.put("type", capability.getType().getName()); dependencies.put("type", capability.getType().getName());
map.put("values", ArrayNode values = nodeFactory.arrayNode();
capability.getContent().stream().map(this::mapDependencyGroup) values.addAll(capability.getContent().stream().map(this::mapDependencyGroup)
.collect(Collectors.toList())); .collect(Collectors.toList()));
parent.put(capability.getId(), map); dependencies.set("values", values);
parent.set(capability.getId(), dependencies);
} }
protected void type(JSONObject parent, TypeCapability capability) { protected void type(ObjectNode parent, TypeCapability capability) {
Map<String, Object> map = new LinkedHashMap<>(); ObjectNode type = nodeFactory.objectNode();
map.put("type", "action"); type.put("type", "action");
Type defaultType = capability.getDefault(); Type defaultType = capability.getDefault();
if (defaultType != null) { if (defaultType != null) {
map.put("default", defaultType.getId()); type.put("default", defaultType.getId());
} }
map.put("values", capability.getContent().stream().map(this::mapType) ArrayNode values = nodeFactory.arrayNode();
values.addAll(capability.getContent().stream().map(this::mapType)
.collect(Collectors.toList())); .collect(Collectors.toList()));
parent.put("type", map); type.set("values", values);
parent.set("type", type);
} }
protected void singleSelect(JSONObject parent, SingleSelectCapability capability) { protected void singleSelect(ObjectNode parent, SingleSelectCapability capability) {
Map<String, Object> map = new LinkedHashMap<>(); ObjectNode single = nodeFactory.objectNode();
map.put("type", capability.getType().getName()); single.put("type", capability.getType().getName());
DefaultMetadataElement defaultType = capability.getDefault(); DefaultMetadataElement defaultType = capability.getDefault();
if (defaultType != null) { if (defaultType != null) {
map.put("default", defaultType.getId()); single.put("default", defaultType.getId());
} }
map.put("values", capability.getContent().stream().map(this::mapValue) ArrayNode values = nodeFactory.arrayNode();
values.addAll(capability.getContent().stream().map(this::mapValue)
.collect(Collectors.toList())); .collect(Collectors.toList()));
parent.put(capability.getId(), map); single.set("values", values);
parent.set(capability.getId(), single);
} }
protected void text(JSONObject parent, TextCapability capability) { protected void text(ObjectNode parent, TextCapability capability) {
Map<String, Object> map = new LinkedHashMap<>(); ObjectNode text = nodeFactory.objectNode();
map.put("type", capability.getType().getName()); text.put("type", capability.getType().getName());
String defaultValue = capability.getContent(); String defaultValue = capability.getContent();
if (StringUtils.hasText(defaultValue)) { if (StringUtils.hasText(defaultValue)) {
map.put("default", defaultValue); text.put("default", defaultValue);
} }
parent.put(capability.getId(), map); parent.set(capability.getId(), text);
} }
protected Map<String, Object> mapDependencyGroup(DependencyGroup group) { protected ObjectNode mapDependencyGroup(DependencyGroup group) {
Map<String, Object> result = new LinkedHashMap<>(); ObjectNode result = nodeFactory.objectNode();
result.put("name", group.getName()); result.put("name", group.getName());
if ((group instanceof Describable) if ((group instanceof Describable)
&& ((Describable) group).getDescription() != null) { && ((Describable) group).getDescription() != null) {
result.put("description", ((Describable) group).getDescription()); result.put("description", ((Describable) group).getDescription());
} }
List<Object> items = new ArrayList<>(); ArrayNode items = nodeFactory.arrayNode();
group.getContent().forEach(it -> { group.getContent().forEach(it -> {
Map<String, Object> dependency = mapDependency(it); JsonNode dependency = mapDependency(it);
if (dependency != null) { if (dependency != null) {
items.add(dependency); items.add(dependency);
} }
}); });
result.put("values", items); result.set("values", items);
return result; return result;
} }
protected Map<String, Object> mapDependency(Dependency dependency) { protected ObjectNode mapDependency(Dependency dependency) {
if (dependency.getVersionRange() == null) { if (dependency.getVersionRange() == null) {
// only map the dependency if no versionRange is set // only map the dependency if no versionRange is set
return mapValue(dependency); return mapValue(dependency);
@ -183,15 +194,17 @@ public class InitializrMetadataV2JsonMapper implements InitializrMetadataJsonMap
return null; return null;
} }
protected Map<String, Object> mapType(Type type) { protected ObjectNode mapType(Type type) {
Map<String, Object> result = mapValue(type); ObjectNode result = mapValue(type);
result.put("action", type.getAction()); result.put("action", type.getAction());
result.put("tags", type.getTags()); ObjectNode tags = nodeFactory.objectNode();
type.getTags().forEach(tags::put);
result.set("tags", tags);
return result; return result;
} }
protected Map<String, Object> mapValue(MetadataElement value) { protected ObjectNode mapValue(MetadataElement value) {
Map<String, Object> result = new LinkedHashMap<>(); ObjectNode result = nodeFactory.objectNode();
result.put("id", value.getId()); result.put("id", value.getId());
result.put("name", value.getName()); result.put("name", value.getName());
if ((value instanceof Describable) if ((value instanceof Describable)

View File

@ -21,6 +21,9 @@ import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
import io.spring.initializr.metadata.Link; import io.spring.initializr.metadata.Link;
/** /**
@ -30,43 +33,45 @@ import io.spring.initializr.metadata.Link;
*/ */
public class LinkMapper { public class LinkMapper {
private static final JsonNodeFactory nodeFactory = JsonNodeFactory.instance;
/** /**
* Map the specified links to a json model. If several links share the same relation, * Map the specified links to a json model. If several links share the same relation,
* they are grouped together. * they are grouped together.
* @param links the links to map * @param links the links to map
* @return a model for the specified links * @return a model for the specified links
*/ */
public static Map<String, Object> mapLinks(List<Link> links) { public static ObjectNode mapLinks(List<Link> links) {
Map<String, Object> result = new LinkedHashMap<>(); ObjectNode result = nodeFactory.objectNode();
Map<String, List<Link>> byRel = new LinkedHashMap<>(); Map<String, List<Link>> byRel = new LinkedHashMap<>();
links.forEach(it -> byRel.computeIfAbsent(it.getRel(), links.forEach(it -> byRel.computeIfAbsent(it.getRel(),
k -> new ArrayList<>()).add(it)); k -> new ArrayList<>()).add(it));
byRel.forEach((rel, l) -> { byRel.forEach((rel, l) -> {
if (l.size() == 1) { if (l.size() == 1) {
Map<String, Object> root = new LinkedHashMap<>(); ObjectNode root = JsonNodeFactory.instance.objectNode();
mapLink(l.get(0), root); mapLink(l.get(0), root);
result.put(rel, root); result.set(rel, root);
} }
else { else {
List<Map<String, Object>> root = new ArrayList<>(); ArrayNode root = JsonNodeFactory.instance.arrayNode();
l.forEach(link -> { l.forEach(link -> {
Map<String, Object> model = new LinkedHashMap<>(); ObjectNode node = JsonNodeFactory.instance.objectNode();
mapLink(link, model); mapLink(link, node);
root.add(model); root.add(node);
}); });
result.put(rel, root); result.set(rel, root);
} }
}); });
return result; return result;
} }
private static void mapLink(Link link, Map<String, Object> model) { private static void mapLink(Link link, ObjectNode node) {
model.put("href", link.getHref()); node.put("href", link.getHref());
if (link.isTemplated()) { if (link.isTemplated()) {
model.put("templated", true); node.put("templated", true);
} }
if (link.getDescription() != null) { if (link.getDescription() != null) {
model.put("title", link.getDescription()); node.put("title", link.getDescription());
} }
} }

View File

@ -18,6 +18,7 @@ package io.spring.initializr.web.support;
import java.util.List; import java.util.List;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.spring.initializr.metadata.DefaultMetadataElement; import io.spring.initializr.metadata.DefaultMetadataElement;
import io.spring.initializr.metadata.InitializrMetadata; import io.spring.initializr.metadata.InitializrMetadata;
import io.spring.initializr.metadata.InitializrMetadataProvider; import io.spring.initializr.metadata.InitializrMetadataProvider;
@ -40,11 +41,13 @@ public class DefaultInitializrMetadataProvider implements InitializrMetadataProv
.getLogger(DefaultInitializrMetadataProvider.class); .getLogger(DefaultInitializrMetadataProvider.class);
private final InitializrMetadata metadata; private final InitializrMetadata metadata;
private final ObjectMapper objectMapper;
private final RestTemplate restTemplate; private final RestTemplate restTemplate;
public DefaultInitializrMetadataProvider(InitializrMetadata metadata, public DefaultInitializrMetadataProvider(InitializrMetadata metadata,
RestTemplate restTemplate) { ObjectMapper objectMapper, RestTemplate restTemplate) {
this.metadata = metadata; this.metadata = metadata;
this.objectMapper = objectMapper;
this.restTemplate = restTemplate; this.restTemplate = restTemplate;
} }
@ -71,7 +74,8 @@ public class DefaultInitializrMetadataProvider implements InitializrMetadataProv
if (StringUtils.hasText(url)) { if (StringUtils.hasText(url)) {
try { try {
log.info("Fetching boot metadata from {}", url); log.info("Fetching boot metadata from {}", url);
return new SpringBootMetadataReader(restTemplate, url).getBootVersions(); return new SpringBootMetadataReader(objectMapper, restTemplate, url)
.getBootVersions();
} }
catch (Exception e) { catch (Exception e) {
log.warn("Failed to fetch spring boot metadata", e); log.warn("Failed to fetch spring boot metadata", e);

View File

@ -16,12 +16,14 @@
package io.spring.initializr.web.support; package io.spring.initializr.web.support;
import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import io.spring.initializr.metadata.DefaultMetadataElement; import io.spring.initializr.metadata.DefaultMetadataElement;
import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.web.client.RestTemplate; import org.springframework.web.client.RestTemplate;
@ -33,28 +35,29 @@ import org.springframework.web.client.RestTemplate;
*/ */
public class SpringBootMetadataReader { public class SpringBootMetadataReader {
private final JSONObject content; private final JsonNode content;
/** /**
* Parse the content of the metadata at the specified url * Parse the content of the metadata at the specified url
*/ */
public SpringBootMetadataReader(RestTemplate restTemplate, String url) { public SpringBootMetadataReader(ObjectMapper objectMapper,
this.content = new JSONObject(restTemplate.getForObject(url, String.class)); RestTemplate restTemplate, String url) throws IOException {
this.content = objectMapper.readTree(
restTemplate.getForObject(url, String.class));
} }
/** /**
* Return the boot versions parsed by this instance. * Return the boot versions parsed by this instance.
*/ */
public List<DefaultMetadataElement> getBootVersions() { public List<DefaultMetadataElement> getBootVersions() {
JSONArray array = content.getJSONArray("projectReleases"); ArrayNode array = (ArrayNode) content.get("projectReleases");
List<DefaultMetadataElement> list = new ArrayList<>(); List<DefaultMetadataElement> list = new ArrayList<>();
for (int i = 0; i < array.length(); i++) { for (JsonNode it : array) {
JSONObject it = array.getJSONObject(i);
DefaultMetadataElement version = new DefaultMetadataElement(); DefaultMetadataElement version = new DefaultMetadataElement();
version.setId(it.getString("version")); version.setId(it.get("version").textValue());
String name = it.getString("versionDisplayName"); String name = it.get("versionDisplayName").textValue();
version.setName(it.getBoolean("snapshot") ? name + " (SNAPSHOT)" : name); version.setName(it.get("snapshot").booleanValue() ? name + " (SNAPSHOT)" : name);
version.setDefault(it.getBoolean("current")); version.setDefault(it.get("current").booleanValue());
list.add(version); list.add(version);
} }
return list; return list;

View File

@ -18,15 +18,15 @@ package io.spring.initializr.web.ui;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
import io.spring.initializr.metadata.Dependency; import io.spring.initializr.metadata.Dependency;
import io.spring.initializr.metadata.DependencyGroup; import io.spring.initializr.metadata.DependencyGroup;
import io.spring.initializr.metadata.InitializrMetadataProvider; import io.spring.initializr.metadata.InitializrMetadataProvider;
import io.spring.initializr.util.Version; import io.spring.initializr.util.Version;
import org.json.JSONObject;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
@ -74,31 +74,31 @@ public class UiController {
} }
private static String writeDependencies(List<DependencyItem> items) { private static String writeDependencies(List<DependencyItem> items) {
JSONObject json = new JSONObject(); ObjectNode json = JsonNodeFactory.instance.objectNode();
List<Map<String, Object>> maps = new ArrayList<>(); ArrayNode maps = JsonNodeFactory.instance.arrayNode();
items.forEach(d -> maps.add(mapDependency(d))); items.forEach(d -> maps.add(mapDependency(d)));
json.put("dependencies", maps); json.set("dependencies", maps);
return json.toString(); return json.toString();
} }
private static Map<String, Object> mapDependency(DependencyItem item) { private static ObjectNode mapDependency(DependencyItem item) {
Map<String, Object> result = new HashMap<>(); ObjectNode node = JsonNodeFactory.instance.objectNode();
Dependency d = item.dependency; Dependency d = item.dependency;
result.put("id", d.getId()); node.put("id", d.getId());
result.put("name", d.getName()); node.put("name", d.getName());
result.put("group", item.group); node.put("group", item.group);
if (d.getDescription() != null) { if (d.getDescription() != null) {
result.put("description", d.getDescription()); node.put("description", d.getDescription());
} }
if (d.getWeight() > 0) { if (d.getWeight() > 0) {
result.put("weight", d.getWeight()); node.put("weight", d.getWeight());
} }
if (!CollectionUtils.isEmpty(d.getKeywords()) || !CollectionUtils.isEmpty(d.getAliases())) { if (!CollectionUtils.isEmpty(d.getKeywords()) || !CollectionUtils.isEmpty(d.getAliases())) {
List<String> all = new ArrayList<>(d.getKeywords()); List<String> all = new ArrayList<>(d.getKeywords());
all.addAll(d.getAliases()); all.addAll(d.getAliases());
result.put("keywords", StringUtils.collectionToCommaDelimitedString(all)); node.put("keywords", StringUtils.collectionToCommaDelimitedString(all));
} }
return result; return node;
} }
private static class DependencyItem { private static class DependencyItem {

View File

@ -25,6 +25,8 @@ import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.spring.initializr.metadata.InitializrMetadata; import io.spring.initializr.metadata.InitializrMetadata;
import io.spring.initializr.metadata.InitializrMetadataBuilder; import io.spring.initializr.metadata.InitializrMetadataBuilder;
import io.spring.initializr.metadata.InitializrMetadataProvider; import io.spring.initializr.metadata.InitializrMetadataProvider;
@ -36,6 +38,7 @@ import io.spring.initializr.web.support.DefaultInitializrMetadataProvider;
import org.apache.tools.ant.Project; import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.Expand; import org.apache.tools.ant.taskdefs.Expand;
import org.apache.tools.ant.taskdefs.Untar; import org.apache.tools.ant.taskdefs.Untar;
import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import org.junit.Before; import org.junit.Before;
import org.junit.Rule; import org.junit.Rule;
@ -71,6 +74,8 @@ public abstract class AbstractInitializrIntegrationTests {
protected static final MediaType CURRENT_METADATA_MEDIA_TYPE = protected static final MediaType CURRENT_METADATA_MEDIA_TYPE =
InitializrMetadataVersion.V2_1.getMediaType(); InitializrMetadataVersion.V2_1.getMediaType();
private static final ObjectMapper objectMapper = new ObjectMapper();
@Rule @Rule
public final TemporaryFolder folder = new TemporaryFolder(); public final TemporaryFolder folder = new TemporaryFolder();
@ -103,22 +108,41 @@ public abstract class AbstractInitializrIntegrationTests {
actual.isCompatibleWith(expected)); actual.isCompatibleWith(expected));
} }
protected JsonNode parseJson(String text) {
try {
return objectMapper.readTree(text);
}
catch (IOException ex) {
throw new IllegalArgumentException("Invalid json", ex);
}
}
protected void validateMetadata(ResponseEntity<String> response, MediaType mediaType, protected void validateMetadata(ResponseEntity<String> response, MediaType mediaType,
String version, JSONCompareMode compareMode) { String version, JSONCompareMode compareMode) {
validateContentType(response, mediaType); try {
JSONObject json = new JSONObject(response.getBody()); validateContentType(response, mediaType);
JSONObject expected = readMetadataJson(version); JSONObject json = new JSONObject(response.getBody());
JSONAssert.assertEquals(expected, json, compareMode); JSONObject expected = readMetadataJson(version);
JSONAssert.assertEquals(expected, json, compareMode);
}
catch (JSONException ex) {
throw new IllegalArgumentException("Invalid json", ex);
}
} }
protected void validateCurrentMetadata(ResponseEntity<String> response) { protected void validateCurrentMetadata(ResponseEntity<String> response) {
validateContentType(response, CURRENT_METADATA_MEDIA_TYPE); validateContentType(response, CURRENT_METADATA_MEDIA_TYPE);
validateCurrentMetadata(new JSONObject(response.getBody())); validateCurrentMetadata(response.getBody());
} }
protected void validateCurrentMetadata(JSONObject json) { protected void validateCurrentMetadata(String json) {
JSONObject expected = readMetadataJson("2.1.0"); try {
JSONAssert.assertEquals(expected, json, JSONCompareMode.STRICT); JSONObject expected = readMetadataJson("2.1.0");
JSONAssert.assertEquals(expected, new JSONObject(json), JSONCompareMode.STRICT);
}
catch (JSONException ex) {
throw new IllegalArgumentException("Invalid json", ex);
}
} }
private JSONObject readMetadataJson(String version) { private JSONObject readMetadataJson(String version) {
@ -205,7 +229,7 @@ public abstract class AbstractInitializrIntegrationTests {
expand.setSrc(archiveFile); expand.setSrc(archiveFile);
Untar.UntarCompressionMethod method = new Untar.UntarCompressionMethod(); Untar.UntarCompressionMethod method = new Untar.UntarCompressionMethod();
method.setValue("gzip"); method.setValue("gzip");
expand.setCompression(method ); expand.setCompression(method);
expand.execute(); expand.execute();
} }
@ -267,7 +291,8 @@ public abstract class AbstractInitializrIntegrationTests {
public InitializrMetadataProvider initializrMetadataProvider( public InitializrMetadataProvider initializrMetadataProvider(
InitializrProperties properties) { InitializrProperties properties) {
return new DefaultInitializrMetadataProvider(InitializrMetadataBuilder return new DefaultInitializrMetadataProvider(InitializrMetadataBuilder
.fromInitializrProperties(properties).build(), new RestTemplate()) { .fromInitializrProperties(properties).build(), new ObjectMapper(),
new RestTemplate()) {
@Override @Override
protected void updateInitializrMetadata(InitializrMetadata metadata) { protected void updateInitializrMetadata(InitializrMetadata metadata) {
// Disable metadata fetching from spring.io // Disable metadata fetching from spring.io

View File

@ -21,6 +21,7 @@ import org.junit.After;
import org.junit.Test; import org.junit.Test;
import org.springframework.beans.DirectFieldAccessor; import org.springframework.beans.DirectFieldAccessor;
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
import org.springframework.boot.autoconfigure.web.WebClientAutoConfiguration; import org.springframework.boot.autoconfigure.web.WebClientAutoConfiguration;
import org.springframework.boot.test.util.EnvironmentTestUtils; import org.springframework.boot.test.util.EnvironmentTestUtils;
import org.springframework.boot.web.client.RestTemplateCustomizer; import org.springframework.boot.web.client.RestTemplateCustomizer;
@ -68,7 +69,8 @@ public class InitializrAutoConfigurationTests {
if (config != null) { if (config != null) {
ctx.register(config); ctx.register(config);
} }
ctx.register(WebClientAutoConfiguration.class, InitializrAutoConfiguration.class); ctx.register(WebClientAutoConfiguration.class, JacksonAutoConfiguration.class,
InitializrAutoConfiguration.class);
ctx.refresh(); ctx.refresh();
this.context = ctx; this.context = ctx;
} }

View File

@ -16,11 +16,14 @@
package io.spring.initializr.web.mapper; package io.spring.initializr.web.mapper;
import java.io.IOException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.spring.initializr.metadata.Dependency; import io.spring.initializr.metadata.Dependency;
import io.spring.initializr.metadata.InitializrMetadata; import io.spring.initializr.metadata.InitializrMetadata;
import io.spring.initializr.metadata.Link; import io.spring.initializr.metadata.Link;
import io.spring.initializr.test.metadata.InitializrMetadataTestBuilder; import io.spring.initializr.test.metadata.InitializrMetadataTestBuilder;
import org.json.JSONObject;
import org.junit.Test; import org.junit.Test;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
@ -31,27 +34,29 @@ import static org.junit.Assert.assertTrue;
*/ */
public class InitializrMetadataJsonMapperTests { public class InitializrMetadataJsonMapperTests {
private static final ObjectMapper objectMapper = new ObjectMapper();
private final InitializrMetadataJsonMapper jsonMapper = private final InitializrMetadataJsonMapper jsonMapper =
new InitializrMetadataV21JsonMapper(); new InitializrMetadataV21JsonMapper();
@Test @Test
public void withNoAppUrl() { public void withNoAppUrl() throws IOException {
InitializrMetadata metadata = new InitializrMetadataTestBuilder() InitializrMetadata metadata = new InitializrMetadataTestBuilder()
.addType("foo", true, "/foo.zip", "none", "test") .addType("foo", true, "/foo.zip", "none", "test")
.addDependencyGroup("foo", "one", "two").build(); .addDependencyGroup("foo", "one", "two").build();
String json = jsonMapper.write(metadata, null); String json = jsonMapper.write(metadata, null);
JSONObject result = new JSONObject(json); JsonNode result = objectMapper.readTree(json);
assertEquals("/foo.zip?type=foo{&dependencies,packaging,javaVersion,language,bootVersion," + assertEquals("/foo.zip?type=foo{&dependencies,packaging,javaVersion,language,bootVersion," +
"groupId,artifactId,version,name,description,packageName}", get(result, "_links.foo.href")); "groupId,artifactId,version,name,description,packageName}", get(result, "_links.foo.href"));
} }
@Test @Test
public void withAppUrl() { public void withAppUrl() throws IOException {
InitializrMetadata metadata = new InitializrMetadataTestBuilder() InitializrMetadata metadata = new InitializrMetadataTestBuilder()
.addType("foo", true, "/foo.zip", "none", "test") .addType("foo", true, "/foo.zip", "none", "test")
.addDependencyGroup("foo", "one", "two").build(); .addDependencyGroup("foo", "one", "two").build();
String json = jsonMapper.write(metadata, "http://server:8080/my-app"); String json = jsonMapper.write(metadata, "http://server:8080/my-app");
JSONObject result = new JSONObject(json); JsonNode result = objectMapper.readTree(json);
assertEquals("http://server:8080/my-app/foo.zip?type=foo{&dependencies,packaging,javaVersion," + assertEquals("http://server:8080/my-app/foo.zip?type=foo{&dependencies,packaging,javaVersion," +
"language,bootVersion,groupId,artifactId,version,name,description,packageName}", "language,bootVersion,groupId,artifactId,version,name,description,packageName}",
get(result, "_links.foo.href")); get(result, "_links.foo.href"));
@ -72,13 +77,13 @@ public class InitializrMetadataJsonMapperTests {
assertTrue(second > 0); assertTrue(second > 0);
} }
private Object get(JSONObject result, String path) { private Object get(JsonNode result, String path) {
String[] nodes = path.split("\\."); String[] nodes = path.split("\\.");
for (int i = 0; i < nodes.length - 1; i++) { for (int i = 0; i < nodes.length - 1; i++) {
String node = nodes[i]; String node = nodes[i];
result = result.getJSONObject(node); result = result.path(node);
} }
return result.getString(nodes[nodes.length - 1]); return result.get(nodes[nodes.length - 1]).textValue();
} }
} }

View File

@ -18,8 +18,9 @@ package io.spring.initializr.web.mapper;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import io.spring.initializr.metadata.Link; import io.spring.initializr.metadata.Link;
import org.junit.Test; import org.junit.Test;
@ -37,28 +38,27 @@ public class LinkMapperTests {
public void mapSimpleRel() { public void mapSimpleRel() {
List<Link> links = new ArrayList<>(); List<Link> links = new ArrayList<>();
links.add(Link.create("a", "https://example.com", "some description")); links.add(Link.create("a", "https://example.com", "some description"));
Map<String, Object> model = LinkMapper.mapLinks(links); ObjectNode model = LinkMapper.mapLinks(links);
assertEquals(1, model.size()); assertEquals(1, model.size());
assertTrue(model.containsKey("a")); assertTrue(model.has("a"));
@SuppressWarnings("unchecked") ObjectNode linkModel = (ObjectNode) model.get("a");
Map<String, Object> linkModel = (Map<String, Object>) model.get("a");
assertEquals(2, linkModel.size()); assertEquals(2, linkModel.size());
assertEquals("https://example.com", linkModel.get("href")); assertEquals("https://example.com", linkModel.get("href").textValue());
assertEquals("some description", linkModel.get("title")); assertEquals("some description", linkModel.get("title").textValue());
} }
@Test @Test
public void mapTemplatedRel() { public void mapTemplatedRel() {
List<Link> links = new ArrayList<>(); List<Link> links = new ArrayList<>();
links.add(Link.create("a", "https://example.com/{bootVersion}/a", true)); links.add(Link.create("a", "https://example.com/{bootVersion}/a", true));
Map<String, Object> model = LinkMapper.mapLinks(links); ObjectNode model = LinkMapper.mapLinks(links);
assertEquals(1, model.size()); assertEquals(1, model.size());
assertTrue(model.containsKey("a")); assertTrue(model.has("a"));
@SuppressWarnings("unchecked") ObjectNode linkModel = (ObjectNode) model.get("a");
Map<String, Object> linkModel = (Map<String, Object>) model.get("a");
assertEquals(2, linkModel.size()); assertEquals(2, linkModel.size());
assertEquals("https://example.com/{bootVersion}/a", linkModel.get("href")); assertEquals("https://example.com/{bootVersion}/a",
assertEquals(true, linkModel.get("templated")); linkModel.get("href").textValue());
assertEquals(true, linkModel.get("templated").booleanValue());
} }
@Test @Test
@ -66,33 +66,34 @@ public class LinkMapperTests {
List<Link> links = new ArrayList<>(); List<Link> links = new ArrayList<>();
links.add(Link.create("a", "https://example.com", "some description")); links.add(Link.create("a", "https://example.com", "some description"));
links.add(Link.create("a", "https://example.com/2")); links.add(Link.create("a", "https://example.com/2"));
Map<String, Object> model = LinkMapper.mapLinks(links); ObjectNode model = LinkMapper.mapLinks(links);
assertEquals(1, model.size()); assertEquals(1, model.size());
assertTrue(model.containsKey("a")); assertTrue(model.has("a"));
@SuppressWarnings("unchecked") ArrayNode linksModel = (ArrayNode) model.get("a");
List<Map<String, Object>> linksModel = (List<Map<String, Object>>) model.get("a");
assertEquals(2, linksModel.size()); assertEquals(2, linksModel.size());
assertEquals("https://example.com", linksModel.get(0).get("href")); assertEquals("https://example.com", linksModel.get(0).get("href").textValue());
assertEquals("https://example.com/2", linksModel.get(1).get("href")); assertEquals("https://example.com/2", linksModel.get(1).get("href").textValue());
} }
@Test @Test
public void keepOrdering() { public void keepOrdering() {
List<Link> links = new ArrayList<>(); List<Link> links = new ArrayList<>();
links.add(Link.create("a", "https://example.com")); links.add(Link.create("first", "https://example.com"));
links.add(Link.create("b", "https://example.com")); links.add(Link.create("second", "https://example.com"));
Map<String, Object> model = LinkMapper.mapLinks(links); ObjectNode model = LinkMapper.mapLinks(links);
assertEquals("[a, b]", model.keySet().toString()); String json = model.toString();
assertTrue(json.indexOf("first") < json.indexOf("second"));
} }
@Test @Test
public void keepOrderingWithMultipleUrlForSameRel() { public void keepOrderingWithMultipleUrlForSameRel() {
List<Link> links = new ArrayList<>(); List<Link> links = new ArrayList<>();
links.add(Link.create("a", "https://example.com")); links.add(Link.create("first", "https://example.com"));
links.add(Link.create("b", "https://example.com")); links.add(Link.create("second", "https://example.com"));
links.add(Link.create("a", "https://example.com")); links.add(Link.create("first", "https://example.com"));
Map<String, Object> model = LinkMapper.mapLinks(links); ObjectNode model = LinkMapper.mapLinks(links);
assertEquals("[a, b]", model.keySet().toString()); String json = model.toString();
assertTrue(json.indexOf("first") < json.indexOf("second"));
} }
} }

View File

@ -17,6 +17,7 @@
package io.spring.initializr.web.project; package io.spring.initializr.web.project;
import io.spring.initializr.web.AbstractInitializrControllerIntegrationTests; import io.spring.initializr.web.AbstractInitializrControllerIntegrationTests;
import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import org.junit.Test; import org.junit.Test;
import org.skyscreamer.jsonassert.JSONAssert; import org.skyscreamer.jsonassert.JSONAssert;
@ -38,27 +39,28 @@ public class MainControllerDependenciesTests
extends AbstractInitializrControllerIntegrationTests { extends AbstractInitializrControllerIntegrationTests {
@Test @Test
public void noBootVersion() { public void noBootVersion() throws JSONException {
ResponseEntity<String> response = execute("/dependencies", String.class, null, ResponseEntity<String> response = execute("/dependencies", String.class, null,
"application/json"); "application/json");
assertThat(response.getHeaders().getFirst(HttpHeaders.ETAG), not(nullValue())); assertThat(response.getHeaders().getFirst(HttpHeaders.ETAG), not(nullValue()));
validateContentType(response, CURRENT_METADATA_MEDIA_TYPE); validateContentType(response, CURRENT_METADATA_MEDIA_TYPE);
validateDependenciesOutput("1.1.4", new JSONObject(response.getBody())); validateDependenciesOutput("1.1.4", response.getBody());
} }
@Test @Test
public void filteredDependencies() { public void filteredDependencies() throws JSONException {
ResponseEntity<String> response = execute("/dependencies?bootVersion=1.2.1.RELEASE", ResponseEntity<String> response = execute("/dependencies?bootVersion=1.2.1.RELEASE",
String.class, null, "application/json"); String.class, null, "application/json");
assertThat(response.getHeaders().getFirst(HttpHeaders.ETAG), not(nullValue())); assertThat(response.getHeaders().getFirst(HttpHeaders.ETAG), not(nullValue()));
validateContentType(response, CURRENT_METADATA_MEDIA_TYPE); validateContentType(response, CURRENT_METADATA_MEDIA_TYPE);
validateDependenciesOutput("1.2.1", new JSONObject(response.getBody())); validateDependenciesOutput("1.2.1", response.getBody());
} }
protected void validateDependenciesOutput(String version, JSONObject actual) { protected void validateDependenciesOutput(String version, String actual)
throws JSONException {
JSONObject expected = readJsonFrom( JSONObject expected = readJsonFrom(
"metadata/dependencies/test-dependencies-" + version + ".json"); "metadata/dependencies/test-dependencies-" + version + ".json");
JSONAssert.assertEquals(expected, actual, JSONCompareMode.STRICT); JSONAssert.assertEquals(expected, new JSONObject(actual), JSONCompareMode.STRICT);
} }
} }

View File

@ -22,6 +22,7 @@ import java.net.URISyntaxException;
import io.spring.initializr.metadata.Dependency; import io.spring.initializr.metadata.Dependency;
import io.spring.initializr.web.AbstractInitializrControllerIntegrationTests; import io.spring.initializr.web.AbstractInitializrControllerIntegrationTests;
import io.spring.initializr.web.mapper.InitializrMetadataVersion; import io.spring.initializr.web.mapper.InitializrMetadataVersion;
import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import org.junit.Ignore; import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
@ -195,7 +196,7 @@ public class MainControllerIntegrationTests
assertThat(response.getHeaders().getFirst(HttpHeaders.ETAG), not(nullValue())); assertThat(response.getHeaders().getFirst(HttpHeaders.ETAG), not(nullValue()));
validateContentType(response, validateContentType(response,
AbstractInitializrControllerIntegrationTests.CURRENT_METADATA_MEDIA_TYPE); AbstractInitializrControllerIntegrationTests.CURRENT_METADATA_MEDIA_TYPE);
validateCurrentMetadata(new JSONObject(response.getBody())); validateCurrentMetadata(response.getBody());
} }
@Test @Test
@ -205,7 +206,7 @@ public class MainControllerIntegrationTests
"application/vnd.initializr.v2+json"); "application/vnd.initializr.v2+json");
validateContentType(response, validateContentType(response,
AbstractInitializrControllerIntegrationTests.CURRENT_METADATA_MEDIA_TYPE); AbstractInitializrControllerIntegrationTests.CURRENT_METADATA_MEDIA_TYPE);
validateCurrentMetadata(new JSONObject(response.getBody())); validateCurrentMetadata(response.getBody());
} }
@Test @Test
@ -213,7 +214,7 @@ public class MainControllerIntegrationTests
ResponseEntity<String> response = invokeHome(null, "application/hal+json"); ResponseEntity<String> response = invokeHome(null, "application/hal+json");
assertThat(response.getHeaders().getFirst(HttpHeaders.ETAG), not(nullValue())); assertThat(response.getHeaders().getFirst(HttpHeaders.ETAG), not(nullValue()));
validateContentType(response, MainController.HAL_JSON_CONTENT_TYPE); validateContentType(response, MainController.HAL_JSON_CONTENT_TYPE);
validateCurrentMetadata(new JSONObject(response.getBody())); validateCurrentMetadata(response.getBody());
} }
@Test @Test
@ -252,7 +253,7 @@ public class MainControllerIntegrationTests
ResponseEntity<String> response = invokeHome("curl/1.2.4", "application/json"); ResponseEntity<String> response = invokeHome("curl/1.2.4", "application/json");
validateContentType(response, validateContentType(response,
AbstractInitializrControllerIntegrationTests.CURRENT_METADATA_MEDIA_TYPE); AbstractInitializrControllerIntegrationTests.CURRENT_METADATA_MEDIA_TYPE);
validateCurrentMetadata(new JSONObject(response.getBody())); validateCurrentMetadata(response.getBody());
} }
@Test @Test
@ -279,7 +280,7 @@ public class MainControllerIntegrationTests
ResponseEntity<String> response = invokeHome("HTTPie/0.8.0", "application/json"); ResponseEntity<String> response = invokeHome("HTTPie/0.8.0", "application/json");
validateContentType(response, validateContentType(response,
AbstractInitializrControllerIntegrationTests.CURRENT_METADATA_MEDIA_TYPE); AbstractInitializrControllerIntegrationTests.CURRENT_METADATA_MEDIA_TYPE);
validateCurrentMetadata(new JSONObject(response.getBody())); validateCurrentMetadata(response.getBody());
} }
@Test @Test
@ -299,7 +300,7 @@ public class MainControllerIntegrationTests
ResponseEntity<String> response = invokeHome("SpringBootCli/1.2.0", "*/*"); ResponseEntity<String> response = invokeHome("SpringBootCli/1.2.0", "*/*");
validateContentType(response, validateContentType(response,
AbstractInitializrControllerIntegrationTests.CURRENT_METADATA_MEDIA_TYPE); AbstractInitializrControllerIntegrationTests.CURRENT_METADATA_MEDIA_TYPE);
validateCurrentMetadata(new JSONObject(response.getBody())); validateCurrentMetadata(response.getBody());
} }
@Test @Test
@ -311,8 +312,7 @@ public class MainControllerIntegrationTests
@Test @Test
// Test that the current output is exactly what we expect // Test that the current output is exactly what we expect
public void validateCurrentProjectMetadata() { public void validateCurrentProjectMetadata() {
JSONObject json = getMetadataJson(); validateCurrentMetadata(getMetadataJson());
validateCurrentMetadata(json);
} }
private void validateCurlHelpContent(ResponseEntity<String> response) { private void validateCurlHelpContent(ResponseEntity<String> response) {
@ -443,19 +443,23 @@ public class MainControllerIntegrationTests
assertFalse("google analytics should be disabled", body.contains("GoogleAnalyticsObject")); assertFalse("google analytics should be disabled", body.contains("GoogleAnalyticsObject"));
} }
private JSONObject getMetadataJson() { private String getMetadataJson() {
return getMetadataJson(null); return getMetadataJson(null);
} }
private JSONObject getMetadataJson(String userAgentHeader, String... acceptHeaders) { private String getMetadataJson(String userAgentHeader, String... acceptHeaders) {
String json = invokeHome(userAgentHeader, acceptHeaders).getBody(); return invokeHome(userAgentHeader, acceptHeaders).getBody();
return new JSONObject(json);
} }
private static void assertStandardErrorBody(String body, String message) { private static void assertStandardErrorBody(String body, String message) {
assertNotNull("error body must be available", body); assertNotNull("error body must be available", body);
JSONObject model = new JSONObject(body); try {
assertEquals(message, model.get("message")); JSONObject model = new JSONObject(body);
assertEquals(message, model.get("message"));
}
catch (JSONException ex) {
throw new IllegalArgumentException(ex);
}
} }
} }

View File

@ -20,6 +20,7 @@ import io.spring.initializr.metadata.InitializrMetadata;
import io.spring.initializr.metadata.InitializrMetadataBuilder; import io.spring.initializr.metadata.InitializrMetadataBuilder;
import io.spring.initializr.metadata.InitializrMetadataProvider; import io.spring.initializr.metadata.InitializrMetadataProvider;
import io.spring.initializr.web.AbstractFullStackInitializrIntegrationTests; import io.spring.initializr.web.AbstractFullStackInitializrIntegrationTests;
import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import org.junit.Test; import org.junit.Test;
import org.skyscreamer.jsonassert.JSONAssert; import org.skyscreamer.jsonassert.JSONAssert;
@ -77,7 +78,7 @@ public class MainControllerServiceMetadataIntegrationTests
} }
@Test @Test
public void validateJson() { public void validateJson() throws JSONException {
ResponseEntity<String> response = execute("/metadata/config", String.class, null, ResponseEntity<String> response = execute("/metadata/config", String.class, null,
"application/json"); "application/json");
validateContentType(response, MediaType.APPLICATION_JSON); validateContentType(response, MediaType.APPLICATION_JSON);

View File

@ -18,6 +18,7 @@ package io.spring.initializr.web.support;
import java.util.List; import java.util.List;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.spring.initializr.metadata.DefaultMetadataElement; import io.spring.initializr.metadata.DefaultMetadataElement;
import io.spring.initializr.metadata.InitializrMetadata; import io.spring.initializr.metadata.InitializrMetadata;
import io.spring.initializr.test.metadata.InitializrMetadataTestBuilder; import io.spring.initializr.test.metadata.InitializrMetadataTestBuilder;
@ -43,6 +44,8 @@ import static org.springframework.test.web.client.response.MockRestResponseCreat
*/ */
public class DefaultInitializrMetadataProviderTests { public class DefaultInitializrMetadataProviderTests {
private static final ObjectMapper objectMapper = new ObjectMapper();
private RestTemplate restTemplate; private RestTemplate restTemplate;
private MockRestServiceServer mockServer; private MockRestServiceServer mockServer;
@ -61,7 +64,8 @@ public class DefaultInitializrMetadataProviderTests {
.build(); .build();
assertEquals("0.0.9.RELEASE", metadata.getBootVersions().getDefault().getId()); assertEquals("0.0.9.RELEASE", metadata.getBootVersions().getDefault().getId());
DefaultInitializrMetadataProvider provider = DefaultInitializrMetadataProvider provider =
new DefaultInitializrMetadataProvider(metadata, restTemplate); new DefaultInitializrMetadataProvider(metadata, objectMapper,
restTemplate);
expectJson(metadata.getConfiguration().getEnv().getSpringBootMetadataUrl(), expectJson(metadata.getConfiguration().getEnv().getSpringBootMetadataUrl(),
"metadata/sagan/spring-boot.json"); "metadata/sagan/spring-boot.json");
@ -83,7 +87,8 @@ public class DefaultInitializrMetadataProviderTests {
.addBootVersion("0.0.8.RELEASE", false).build(); .addBootVersion("0.0.8.RELEASE", false).build();
assertEquals("0.0.9.RELEASE", metadata.getBootVersions().getDefault().getId()); assertEquals("0.0.9.RELEASE", metadata.getBootVersions().getDefault().getId());
DefaultInitializrMetadataProvider provider = DefaultInitializrMetadataProvider provider =
new DefaultInitializrMetadataProvider(metadata, restTemplate); new DefaultInitializrMetadataProvider(metadata, objectMapper,
restTemplate);
expectJson(metadata.getConfiguration().getEnv().getSpringBootMetadataUrl(), expectJson(metadata.getConfiguration().getEnv().getSpringBootMetadataUrl(),
"metadata/sagan/spring-boot-no-default.json"); "metadata/sagan/spring-boot-no-default.json");

View File

@ -16,9 +16,11 @@
package io.spring.initializr.web.support; package io.spring.initializr.web.support;
import java.io.IOException;
import java.util.List; import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.spring.initializr.metadata.DefaultMetadataElement; import io.spring.initializr.metadata.DefaultMetadataElement;
import io.spring.initializr.metadata.InitializrMetadata; import io.spring.initializr.metadata.InitializrMetadata;
import io.spring.initializr.metadata.InitializrMetadataBuilder; import io.spring.initializr.metadata.InitializrMetadataBuilder;
@ -43,20 +45,22 @@ public class SpringBootMetadataReaderTests {
private final InitializrMetadata metadata = private final InitializrMetadata metadata =
InitializrMetadataBuilder.create().build(); InitializrMetadataBuilder.create().build();
private final ObjectMapper objectMapper = new ObjectMapper();
private final RestTemplate restTemplate = new RestTemplate(); private final RestTemplate restTemplate = new RestTemplate();
private final MockRestServiceServer server = private final MockRestServiceServer server =
MockRestServiceServer.bindTo(restTemplate).build(); MockRestServiceServer.bindTo(restTemplate).build();
@Test @Test
public void readAvailableVersions() { public void readAvailableVersions() throws IOException {
server.expect(requestTo("https://spring.io/project_metadata/spring-boot")) server.expect(requestTo("https://spring.io/project_metadata/spring-boot"))
.andRespond(withSuccess( .andRespond(withSuccess(
new ClassPathResource("metadata/sagan/spring-boot.json"), new ClassPathResource("metadata/sagan/spring-boot.json"),
MediaType.APPLICATION_JSON)); MediaType.APPLICATION_JSON));
List<DefaultMetadataElement> versions = new SpringBootMetadataReader(restTemplate, List<DefaultMetadataElement> versions = new SpringBootMetadataReader(objectMapper,
metadata.getConfiguration().getEnv() restTemplate, metadata.getConfiguration().getEnv()
.getSpringBootMetadataUrl()).getBootVersions(); .getSpringBootMetadataUrl()).getBootVersions();
assertNotNull("spring boot versions should not be null", versions); assertNotNull("spring boot versions should not be null", versions);
AtomicBoolean defaultFound = new AtomicBoolean(false); AtomicBoolean defaultFound = new AtomicBoolean(false);
versions.forEach(it -> { versions.forEach(it -> {

View File

@ -17,6 +17,7 @@
package io.spring.initializr.web.ui; package io.spring.initializr.web.ui;
import io.spring.initializr.web.AbstractInitializrControllerIntegrationTests; import io.spring.initializr.web.AbstractInitializrControllerIntegrationTests;
import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import org.junit.Test; import org.junit.Test;
import org.skyscreamer.jsonassert.JSONAssert; import org.skyscreamer.jsonassert.JSONAssert;
@ -34,23 +35,24 @@ public class UiControllerIntegrationTests
extends AbstractInitializrControllerIntegrationTests { extends AbstractInitializrControllerIntegrationTests {
@Test @Test
public void dependenciesNoVersion() { public void dependenciesNoVersion() throws JSONException {
ResponseEntity<String> response = execute("/ui/dependencies", String.class, null); ResponseEntity<String> response = execute("/ui/dependencies", String.class, null);
validateContentType(response, MediaType.APPLICATION_JSON); validateContentType(response, MediaType.APPLICATION_JSON);
validateDependenciesOutput("all", new JSONObject(response.getBody())); validateDependenciesOutput("all", response.getBody());
} }
@Test @Test
public void dependenciesSpecificVersion() { public void dependenciesSpecificVersion() throws JSONException {
ResponseEntity<String> response = execute( ResponseEntity<String> response = execute(
"/ui/dependencies?version=1.1.2.RELEASE", String.class, null); "/ui/dependencies?version=1.1.2.RELEASE", String.class, null);
validateContentType(response, MediaType.APPLICATION_JSON); validateContentType(response, MediaType.APPLICATION_JSON);
validateDependenciesOutput("1.1.2", new JSONObject(response.getBody())); validateDependenciesOutput("1.1.2", response.getBody());
} }
protected void validateDependenciesOutput(String version, JSONObject actual) { protected void validateDependenciesOutput(String version, String actual)
throws JSONException {
JSONObject expected = readJsonFrom( JSONObject expected = readJsonFrom(
"metadata/ui/test-dependencies-" + version + ".json"); "metadata/ui/test-dependencies-" + version + ".json");
JSONAssert.assertEquals(expected, actual, JSONCompareMode.STRICT); JSONAssert.assertEquals(expected, new JSONObject(actual), JSONCompareMode.STRICT);
} }
} }

View File

@ -92,6 +92,11 @@
<type>pom</type> <type>pom</type>
<scope>import</scope> <scope>import</scope>
</dependency> </dependency>
<dependency>
<groupId>com.vaadin.external.google</groupId>
<artifactId>android-json</artifactId>
<version>0.0.20131108.vaadin1</version>
</dependency>
<dependency> <dependency>
<groupId>xmlunit</groupId> <groupId>xmlunit</groupId>
<artifactId>xmlunit</artifactId> <artifactId>xmlunit</artifactId>