Skip to content

Commit 56dffe0

Browse files
committed
Add SelectItem to flow single selector api
- This change makes single/multi same on an api level where single selector used key/value map and multi selector used list of SelectItem's. - We still keep use of map on a single select but those essentially go directly via SelectItem's. - Fixes #946
1 parent 934fcbd commit 56dffe0

File tree

5 files changed

+68
-18
lines changed

5 files changed

+68
-18
lines changed

spring-shell-core/src/main/java/org/springframework/shell/component/flow/BaseSingleItemSelector.java

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2022 the original author or authors.
2+
* Copyright 2022-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -17,11 +17,11 @@
1717

1818
import java.util.ArrayList;
1919
import java.util.Comparator;
20-
import java.util.HashMap;
2120
import java.util.List;
2221
import java.util.Map;
2322
import java.util.function.Consumer;
2423
import java.util.function.Function;
24+
import java.util.stream.Collectors;
2525

2626
import org.jline.utils.AttributedString;
2727

@@ -40,7 +40,7 @@ public abstract class BaseSingleItemSelector extends BaseInput<SingleItemSelecto
4040
private String name;
4141
private String resultValue;
4242
private ResultMode resultMode;
43-
private Map<String, String> selectItems = new HashMap<>();
43+
private List<SelectItem> selectItems = new ArrayList<>();
4444
private String defaultSelect;
4545
private Comparator<SelectorItem<String>> comparator;
4646
private Function<SingleItemSelectorContext<String, SelectorItem<String>>, List<AttributedString>> renderer;
@@ -75,13 +75,22 @@ public SingleItemSelectorSpec resultMode(ResultMode resultMode) {
7575

7676
@Override
7777
public SingleItemSelectorSpec selectItem(String name, String item) {
78-
this.selectItems.put(name, item);
78+
selectItems.add(SelectItem.of(name, item));
7979
return this;
8080
}
8181

8282
@Override
8383
public SingleItemSelectorSpec selectItems(Map<String, String> selectItems) {
84-
this.selectItems.putAll(selectItems);
84+
List<SelectItem> items = selectItems.entrySet().stream()
85+
.map(e -> SelectItem.of(e.getKey(), e.getValue()))
86+
.collect(Collectors.toList());
87+
selectItems(items);
88+
return this;
89+
}
90+
91+
@Override
92+
public SingleItemSelectorSpec selectItems(List<SelectItem> selectItems) {
93+
this.selectItems.addAll(selectItems);
8594
return this;
8695
}
8796

@@ -163,7 +172,7 @@ public ResultMode getResultMode() {
163172
return resultMode;
164173
}
165174

166-
public Map<String, String> getSelectItems() {
175+
public List<SelectItem> getSelectItems() {
167176
return selectItems;
168177
}
169178

@@ -202,4 +211,4 @@ public boolean isStoreResult() {
202211
public Function<SingleItemSelectorContext<String, SelectorItem<String>>, String> getNext() {
203212
return next;
204213
}
205-
}
214+
}

spring-shell-core/src/main/java/org/springframework/shell/component/flow/ComponentFlow.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2022 the original author or authors.
2+
* Copyright 2022-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -565,9 +565,9 @@ private Stream<OrderedInputOperation> confirmationInputsStream() {
565565

566566
private Stream<OrderedInputOperation> singleItemSelectorsStream() {
567567
return singleInputs.stream().map(input -> {
568-
List<SelectorItem<String>> selectorItems = input.getSelectItems().entrySet().stream()
569-
.map(e -> SelectorItem.of(e.getKey(), e.getValue()))
570-
.collect(Collectors.toList());
568+
List<SelectorItem<String>> selectorItems = input.getSelectItems().stream()
569+
.map(si -> SelectorItem.of(si.name(), si.item()))
570+
.collect(Collectors.toList());
571571

572572
// setup possible item for initial expose
573573
String defaultSelect = input.getDefaultSelect();

spring-shell-core/src/main/java/org/springframework/shell/component/flow/SingleItemSelectorSpec.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2022 the original author or authors.
2+
* Copyright 2022-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -65,6 +65,7 @@ public interface SingleItemSelectorSpec extends BaseInputSpec<SingleItemSelector
6565
* @param name the name
6666
* @param item the item
6767
* @return a builder
68+
* @see #selectItems(List)
6869
*/
6970
SingleItemSelectorSpec selectItem(String name, String item);
7071

@@ -73,9 +74,18 @@ public interface SingleItemSelectorSpec extends BaseInputSpec<SingleItemSelector
7374
*
7475
* @param selectItems the select items
7576
* @return a builder
77+
* @see #selectItems(List)
7678
*/
7779
SingleItemSelectorSpec selectItems(Map<String, String> selectItems);
7880

81+
/**
82+
* Adds a list of select items.
83+
*
84+
* @param selectItems the select items
85+
* @return a builder
86+
*/
87+
SingleItemSelectorSpec selectItems(List<SelectItem> selectItems);
88+
7989
/**
8090
* Automatically selects and exposes a given item.
8191
*
@@ -156,4 +166,4 @@ public interface SingleItemSelectorSpec extends BaseInputSpec<SingleItemSelector
156166
* @return the parent builder
157167
*/
158168
Builder and();
159-
}
169+
}

spring-shell-core/src/test/java/org/springframework/shell/component/flow/ComponentFlowTests.java

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2022 the original author or authors.
2+
* Copyright 2022-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -28,7 +28,9 @@
2828

2929
import org.junit.jupiter.api.Test;
3030

31+
import org.springframework.shell.component.flow.ComponentFlow.Builder;
3132
import org.springframework.shell.component.flow.ComponentFlow.ComponentFlowResult;
33+
import org.springframework.test.util.ReflectionTestUtils;
3234

3335
import static org.assertj.core.api.Assertions.assertThat;
3436

@@ -339,4 +341,34 @@ public void testAutoShowsDefault() throws InterruptedException {
339341
String single1 = inputWizardResult.getContext().get("single1");
340342
assertThat(single1).isEqualTo("value2");
341343
}
344+
345+
@Test
346+
@SuppressWarnings("unchecked")
347+
public void testBuilderSingleTypes() {
348+
List<SelectItem> selectItems1 = Arrays.asList(SelectItem.of("key1", "value1"), SelectItem.of("key2", "value2"));
349+
Map<String, String> selectItems2 = new HashMap<>();
350+
selectItems2.put("key2", "value2");
351+
selectItems2.put("key3", "value3");
352+
353+
Builder builder1 = ComponentFlow.builder()
354+
.withSingleItemSelector("field1")
355+
.selectItems(selectItems1)
356+
.and();
357+
Builder builder2 = ComponentFlow.builder()
358+
.withSingleItemSelector("field2")
359+
.selectItems(selectItems2)
360+
.and();
361+
362+
List<BaseSingleItemSelector> field1 = (List<BaseSingleItemSelector>) ReflectionTestUtils.getField(builder1,
363+
"singleItemSelectors");
364+
List<BaseSingleItemSelector> field2 = (List<BaseSingleItemSelector>) ReflectionTestUtils.getField(builder2,
365+
"singleItemSelectors");
366+
assertThat(field1).hasSize(1);
367+
assertThat(field2).hasSize(1);
368+
369+
List<SelectItem> selectItems11 = (List<SelectItem>) ReflectionTestUtils.getField(field1.get(0), "selectItems");
370+
List<SelectItem> selectItems21 = (List<SelectItem>) ReflectionTestUtils.getField(field2.get(0), "selectItems");
371+
assertThat(selectItems11).hasSize(2);
372+
assertThat(selectItems21).hasSize(2);
373+
}
342374
}

spring-shell-docs/src/test/java/org/springframework/shell/docs/FlowComponentSnippets.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2022 the original author or authors.
2+
* Copyright 2022-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -33,9 +33,8 @@ static class FlowSampleComplex {
3333
private ComponentFlow.Builder componentFlowBuilder;
3434

3535
public void runFlow() {
36-
Map<String, String> single1SelectItems = new HashMap<>();
37-
single1SelectItems.put("key1", "value1");
38-
single1SelectItems.put("key2", "value2");
36+
List<SelectItem> single1SelectItems = Arrays.asList(SelectItem.of("key1", "value1"),
37+
SelectItem.of("key2", "value2"));
3938
List<SelectItem> multi1SelectItems = Arrays.asList(SelectItem.of("key1", "value1"),
4039
SelectItem.of("key2", "value2"), SelectItem.of("key3", "value3"));
4140
ComponentFlow flow = componentFlowBuilder.clone().reset()

0 commit comments

Comments
 (0)