From b170523ffaf1122ff560b7e4e5f51549ec2f0235 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Mon, 14 Dec 2020 10:05:18 +0100 Subject: [PATCH] Add support for lists with nested structure Previously, a nested structure of a Maven Plugin configuration can be only configured for a single parameter. This commit adds a dedicated method to add a new entry with a nested structure every time it is called. This effectively allows to configure nested "list" structure such as listing dependency exclusions. Closes gh-1165 --- .../buildsystem/maven/MavenPlugin.java | 21 +++++++++++-- .../buildsystem/maven/MavenPluginTests.java | 31 ++++++++++++++++++- 2 files changed, 49 insertions(+), 3 deletions(-) diff --git a/initializr-generator/src/main/java/io/spring/initializr/generator/buildsystem/maven/MavenPlugin.java b/initializr-generator/src/main/java/io/spring/initializr/generator/buildsystem/maven/MavenPlugin.java index f7e3a8d2..4cfdc3ed 100644 --- a/initializr-generator/src/main/java/io/spring/initializr/generator/buildsystem/maven/MavenPlugin.java +++ b/initializr-generator/src/main/java/io/spring/initializr/generator/buildsystem/maven/MavenPlugin.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2020 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. @@ -284,12 +284,29 @@ public class MavenPlugin { } /** - * Configure the parameter with the specified {@code name}. + * Add the specified parameter with a nested structure. + * @param name the name of the parameter + * @param consumer a consumer to further configure the parameter + * @return this for method chaining + * @see #configure(String, Consumer) name + */ + public ConfigurationBuilder add(String name, Consumer consumer) { + ConfigurationBuilder nestedConfiguration = new ConfigurationBuilder(); + consumer.accept(nestedConfiguration); + this.settings.add(new Setting(name, nestedConfiguration)); + return this; + } + + /** + * Configure the parameter with the specified {@code name}. If no parameter with + * that name exists, it is created. If the parameter already exists, the consumer + * can be used to further tune the nested structure. * @param name the name of the parameter * @param consumer a consumer to further configure the parameter * @return this for method chaining * @throws IllegalArgumentException if a parameter with the same name is * registered with a single value + * @see #add(String, Consumer) */ public ConfigurationBuilder configure(String name, Consumer consumer) { Object value = this.settings.stream().filter((candidate) -> candidate.getName().equals(name)).findFirst() diff --git a/initializr-generator/src/test/java/io/spring/initializr/generator/buildsystem/maven/MavenPluginTests.java b/initializr-generator/src/test/java/io/spring/initializr/generator/buildsystem/maven/MavenPluginTests.java index 823c3d79..63be5335 100644 --- a/initializr-generator/src/test/java/io/spring/initializr/generator/buildsystem/maven/MavenPluginTests.java +++ b/initializr-generator/src/test/java/io/spring/initializr/generator/buildsystem/maven/MavenPluginTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2020 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. @@ -54,6 +54,35 @@ class MavenPluginTests { "false"); } + @SuppressWarnings("unchecked") + @Test + void configurationParameterWithNestedValuesCanBeAdded() { + MavenPlugin plugin = plugin("com.example", "test-plugin") + .configuration((configuration) -> configuration.configure("items", (items) -> { + items.add("item", (firstItem) -> firstItem.add("name", "one")); + items.add("item", (secondItem) -> secondItem.add("name", "two")); + })).build(); + assertThat(plugin.getConfiguration().getSettings()).hasSize(1); + Setting setting = plugin.getConfiguration().getSettings().get(0); + assertThat(setting.getName()).isEqualTo("items"); + assertThat(setting.getValue()).isInstanceOf(List.class); + List values = (List) setting.getValue(); + assertThat(values.stream().map(Setting::getName)).containsExactly("item", "item"); + assertThat(values.stream().map(Setting::getValue)).anySatisfy((value) -> { + assertThat(value).isInstanceOf(List.class); + List itemValues = (List) value; + assertThat(itemValues.stream().map(Setting::getName)).containsExactly("name"); + assertThat(itemValues.stream().map(Setting::getValue)).containsExactly("one"); + }); + assertThat(values.stream().map(Setting::getValue)).anySatisfy((value) -> { + assertThat(value).isInstanceOf(List.class); + List itemValues = (List) value; + assertThat(itemValues.stream().map(Setting::getName)).containsExactly("name"); + assertThat(itemValues.stream().map(Setting::getValue)).containsExactly("two"); + }); + assertThat(values).hasSize(2); + } + @Test @SuppressWarnings("unchecked") void configurationParameterWithNestedValuesCanBeCustomized() {