diff --git a/spring-boot-tools/spring-boot-configuration-metadata/src/main/java/org/springframework/boot/configurationmetadata/RawConfigurationMetadata.java b/spring-boot-tools/spring-boot-configuration-metadata/src/main/java/org/springframework/boot/configurationmetadata/RawConfigurationMetadata.java index ecb10a883a..ab4918cb79 100644 --- a/spring-boot-tools/spring-boot-configuration-metadata/src/main/java/org/springframework/boot/configurationmetadata/RawConfigurationMetadata.java +++ b/spring-boot-tools/spring-boot-configuration-metadata/src/main/java/org/springframework/boot/configurationmetadata/RawConfigurationMetadata.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2015 the original author or authors. + * Copyright 2012-2016 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. @@ -78,11 +78,17 @@ class RawConfigurationMetadata { ConfigurationMetadataSource source = getSource(item.getSourceType()); if (source != null) { String groupId = source.getGroupId(); + String dottedPrefix = groupId + "."; String id = item.getId(); - if (id.startsWith(groupId)) { // match - String name = id.substring(groupId.length() + 1, id.length()); // "." + if (hasLength(groupId) && id.startsWith(dottedPrefix)) { + String name = id.substring(dottedPrefix.length(), id.length()); item.setName(name); } } } + + private static boolean hasLength(String s) { + return (s != null && s.length() > 0); + } + } diff --git a/spring-boot-tools/spring-boot-configuration-metadata/src/test/java/org/springframework/boot/configurationmetadata/ConfigurationMetadataRepositoryJsonBuilderTests.java b/spring-boot-tools/spring-boot-configuration-metadata/src/test/java/org/springframework/boot/configurationmetadata/ConfigurationMetadataRepositoryJsonBuilderTests.java index 4c7f96c425..2320c7a21f 100644 --- a/spring-boot-tools/spring-boot-configuration-metadata/src/test/java/org/springframework/boot/configurationmetadata/ConfigurationMetadataRepositoryJsonBuilderTests.java +++ b/spring-boot-tools/spring-boot-configuration-metadata/src/test/java/org/springframework/boot/configurationmetadata/ConfigurationMetadataRepositoryJsonBuilderTests.java @@ -138,6 +138,22 @@ public class ConfigurationMetadataRepositoryJsonBuilderTests } } + @Test + public void emptyGroups() throws IOException { + InputStream in = getInputStreamFor("empty-groups"); + try { + ConfigurationMetadataRepository repo = ConfigurationMetadataRepositoryJsonBuilder + .create(in).build(); + validateEmptyGroup(repo); + assertThat(repo.getAllGroups()).hasSize(1); + contains(repo.getAllProperties(), "name", "title"); + assertThat(repo.getAllProperties()).hasSize(2); + } + finally { + in.close(); + } + } + @Test public void builderInstancesAreIsolated() throws IOException { InputStream foo = getInputStreamFor("foo"); @@ -241,6 +257,20 @@ public class ConfigurationMetadataRepositoryJsonBuilderTests .get("target")).isEqualTo("java.lang.Integer"); } + private void validateEmptyGroup(ConfigurationMetadataRepository repo) { + ConfigurationMetadataGroup group = repo.getAllGroups().get(""); + contains(group.getSources(), "org.acme.Foo", "org.acme.Bar"); + ConfigurationMetadataSource source = group.getSources().get("org.acme.Foo"); + contains(source.getProperties(), "name"); + assertThat(source.getProperties()).hasSize(1); + ConfigurationMetadataSource source2 = group.getSources() + .get("org.acme.Bar"); + contains(source2.getProperties(), "title"); + assertThat(source2.getProperties()).hasSize(1); + validatePropertyHints(repo.getAllProperties().get("name"), 0, 0); + validatePropertyHints(repo.getAllProperties().get("title"), 0, 0); + } + private void validatePropertyHints(ConfigurationMetadataProperty property, int valueHints, int valueProviders) { assertThat(property.getHints().getValueHints().size()).isEqualTo(valueHints); diff --git a/spring-boot-tools/spring-boot-configuration-metadata/src/test/java/org/springframework/boot/configurationmetadata/JsonReaderTests.java b/spring-boot-tools/spring-boot-configuration-metadata/src/test/java/org/springframework/boot/configurationmetadata/JsonReaderTests.java index d7033526b8..488eab2bc0 100644 --- a/spring-boot-tools/spring-boot-configuration-metadata/src/test/java/org/springframework/boot/configurationmetadata/JsonReaderTests.java +++ b/spring-boot-tools/spring-boot-configuration-metadata/src/test/java/org/springframework/boot/configurationmetadata/JsonReaderTests.java @@ -49,6 +49,18 @@ public class JsonReaderTests extends AbstractConfigurationMetadataTests { readFor("invalid"); } + @Test + public void emptyGroupName() throws IOException { + RawConfigurationMetadata rawMetadata = readFor("empty-groups"); + List items = rawMetadata.getItems(); + assertThat(items).hasSize(2); + + ConfigurationMetadataItem name = items.get(0); + assertProperty(name, "name", "name", String.class, null); + ConfigurationMetadataItem dotTitle = items.get(1); + assertProperty(dotTitle, "title", "title", String.class, null); + } + @Test public void simpleMetadata() throws IOException { RawConfigurationMetadata rawMetadata = readFor("foo"); diff --git a/spring-boot-tools/spring-boot-configuration-metadata/src/test/resources/metadata/configuration-metadata-empty-groups.json b/spring-boot-tools/spring-boot-configuration-metadata/src/test/resources/metadata/configuration-metadata-empty-groups.json new file mode 100644 index 0000000000..14977b264c --- /dev/null +++ b/spring-boot-tools/spring-boot-configuration-metadata/src/test/resources/metadata/configuration-metadata-empty-groups.json @@ -0,0 +1,30 @@ +{ + "groups": [ + { + "name": "", + "type": "org.acme.Foo", + "sourceType": "org.acme.config.FooApp", + "sourceMethod": "foo()", + "description": "This is Foo." + }, + { + "name": "", + "type": "org.acme.Bar", + "sourceType": "org.acme.config.FooApp", + "sourceMethod": "bar()", + "description": "This is Bar." + } + ], + "properties": [ + { + "name": "name", + "type": "java.lang.String", + "sourceType": "org.acme.Foo" + }, + { + "name": "title", + "type": "java.lang.String", + "sourceType": "org.acme.Bar" + } + ] +}