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. - Backport #946 - Fixes #957
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2022 the original author or authors.
|
* Copyright 2022-2023 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -17,11 +17,11 @@ package org.springframework.shell.component.flow;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.jline.utils.AttributedString;
|
import org.jline.utils.AttributedString;
|
||||||
|
|
||||||
@@ -40,7 +40,7 @@ public abstract class BaseSingleItemSelector extends BaseInput<SingleItemSelecto
|
|||||||
private String name;
|
private String name;
|
||||||
private String resultValue;
|
private String resultValue;
|
||||||
private ResultMode resultMode;
|
private ResultMode resultMode;
|
||||||
private Map<String, String> selectItems = new HashMap<>();
|
private List<SelectItem> selectItems = new ArrayList<>();
|
||||||
private String defaultSelect;
|
private String defaultSelect;
|
||||||
private Comparator<SelectorItem<String>> comparator;
|
private Comparator<SelectorItem<String>> comparator;
|
||||||
private Function<SingleItemSelectorContext<String, SelectorItem<String>>, List<AttributedString>> renderer;
|
private Function<SingleItemSelectorContext<String, SelectorItem<String>>, List<AttributedString>> renderer;
|
||||||
@@ -75,13 +75,22 @@ public abstract class BaseSingleItemSelector extends BaseInput<SingleItemSelecto
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SingleItemSelectorSpec selectItem(String name, String item) {
|
public SingleItemSelectorSpec selectItem(String name, String item) {
|
||||||
this.selectItems.put(name, item);
|
selectItems.add(SelectItem.of(name, item));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SingleItemSelectorSpec selectItems(Map<String, String> selectItems) {
|
public SingleItemSelectorSpec selectItems(Map<String, String> selectItems) {
|
||||||
this.selectItems.putAll(selectItems);
|
List<SelectItem> items = selectItems.entrySet().stream()
|
||||||
|
.map(e -> SelectItem.of(e.getKey(), e.getValue()))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
selectItems(items);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SingleItemSelectorSpec selectItems(List<SelectItem> selectItems) {
|
||||||
|
this.selectItems.addAll(selectItems);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,7 +172,7 @@ public abstract class BaseSingleItemSelector extends BaseInput<SingleItemSelecto
|
|||||||
return resultMode;
|
return resultMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, String> getSelectItems() {
|
public List<SelectItem> getSelectItems() {
|
||||||
return selectItems;
|
return selectItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -202,4 +211,4 @@ public abstract class BaseSingleItemSelector extends BaseInput<SingleItemSelecto
|
|||||||
public Function<SingleItemSelectorContext<String, SelectorItem<String>>, String> getNext() {
|
public Function<SingleItemSelectorContext<String, SelectorItem<String>>, String> getNext() {
|
||||||
return next;
|
return next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2022 the original author or authors.
|
* Copyright 2022-2023 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -565,9 +565,9 @@ public interface ComponentFlow {
|
|||||||
|
|
||||||
private Stream<OrderedInputOperation> singleItemSelectorsStream() {
|
private Stream<OrderedInputOperation> singleItemSelectorsStream() {
|
||||||
return singleInputs.stream().map(input -> {
|
return singleInputs.stream().map(input -> {
|
||||||
List<SelectorItem<String>> selectorItems = input.getSelectItems().entrySet().stream()
|
List<SelectorItem<String>> selectorItems = input.getSelectItems().stream()
|
||||||
.map(e -> SelectorItem.of(e.getKey(), e.getValue()))
|
.map(si -> SelectorItem.of(si.name(), si.item()))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
// setup possible item for initial expose
|
// setup possible item for initial expose
|
||||||
String defaultSelect = input.getDefaultSelect();
|
String defaultSelect = input.getDefaultSelect();
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2022 the original author or authors.
|
* Copyright 2022-2023 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -65,6 +65,7 @@ public interface SingleItemSelectorSpec extends BaseInputSpec<SingleItemSelector
|
|||||||
* @param name the name
|
* @param name the name
|
||||||
* @param item the item
|
* @param item the item
|
||||||
* @return a builder
|
* @return a builder
|
||||||
|
* @see #selectItems(List)
|
||||||
*/
|
*/
|
||||||
SingleItemSelectorSpec selectItem(String name, String item);
|
SingleItemSelectorSpec selectItem(String name, String item);
|
||||||
|
|
||||||
@@ -73,9 +74,18 @@ public interface SingleItemSelectorSpec extends BaseInputSpec<SingleItemSelector
|
|||||||
*
|
*
|
||||||
* @param selectItems the select items
|
* @param selectItems the select items
|
||||||
* @return a builder
|
* @return a builder
|
||||||
|
* @see #selectItems(List)
|
||||||
*/
|
*/
|
||||||
SingleItemSelectorSpec selectItems(Map<String, String> selectItems);
|
SingleItemSelectorSpec selectItems(Map<String, String> selectItems);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a list of select items.
|
||||||
|
*
|
||||||
|
* @param selectItems the select items
|
||||||
|
* @return a builder
|
||||||
|
*/
|
||||||
|
SingleItemSelectorSpec selectItems(List<SelectItem> selectItems);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Automatically selects and exposes a given item.
|
* Automatically selects and exposes a given item.
|
||||||
*
|
*
|
||||||
@@ -156,4 +166,4 @@ public interface SingleItemSelectorSpec extends BaseInputSpec<SingleItemSelector
|
|||||||
* @return the parent builder
|
* @return the parent builder
|
||||||
*/
|
*/
|
||||||
Builder and();
|
Builder and();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2022 the original author or authors.
|
* Copyright 2022-2023 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -28,7 +28,9 @@ import java.util.concurrent.atomic.AtomicReference;
|
|||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import org.springframework.shell.component.flow.ComponentFlow.Builder;
|
||||||
import org.springframework.shell.component.flow.ComponentFlow.ComponentFlowResult;
|
import org.springframework.shell.component.flow.ComponentFlow.ComponentFlowResult;
|
||||||
|
import org.springframework.test.util.ReflectionTestUtils;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
@@ -339,4 +341,34 @@ public class ComponentFlowTests extends AbstractShellTests {
|
|||||||
String single1 = inputWizardResult.getContext().get("single1");
|
String single1 = inputWizardResult.getContext().get("single1");
|
||||||
assertThat(single1).isEqualTo("value2");
|
assertThat(single1).isEqualTo("value2");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public void testBuilderSingleTypes() {
|
||||||
|
List<SelectItem> selectItems1 = Arrays.asList(SelectItem.of("key1", "value1"), SelectItem.of("key2", "value2"));
|
||||||
|
Map<String, String> selectItems2 = new HashMap<>();
|
||||||
|
selectItems2.put("key2", "value2");
|
||||||
|
selectItems2.put("key3", "value3");
|
||||||
|
|
||||||
|
Builder builder1 = ComponentFlow.builder()
|
||||||
|
.withSingleItemSelector("field1")
|
||||||
|
.selectItems(selectItems1)
|
||||||
|
.and();
|
||||||
|
Builder builder2 = ComponentFlow.builder()
|
||||||
|
.withSingleItemSelector("field2")
|
||||||
|
.selectItems(selectItems2)
|
||||||
|
.and();
|
||||||
|
|
||||||
|
List<BaseSingleItemSelector> field1 = (List<BaseSingleItemSelector>) ReflectionTestUtils.getField(builder1,
|
||||||
|
"singleItemSelectors");
|
||||||
|
List<BaseSingleItemSelector> field2 = (List<BaseSingleItemSelector>) ReflectionTestUtils.getField(builder2,
|
||||||
|
"singleItemSelectors");
|
||||||
|
assertThat(field1).hasSize(1);
|
||||||
|
assertThat(field2).hasSize(1);
|
||||||
|
|
||||||
|
List<SelectItem> selectItems11 = (List<SelectItem>) ReflectionTestUtils.getField(field1.get(0), "selectItems");
|
||||||
|
List<SelectItem> selectItems21 = (List<SelectItem>) ReflectionTestUtils.getField(field2.get(0), "selectItems");
|
||||||
|
assertThat(selectItems11).hasSize(2);
|
||||||
|
assertThat(selectItems21).hasSize(2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2022 the original author or authors.
|
* Copyright 2022-2023 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -33,9 +33,8 @@ public class FlowComponentSnippets {
|
|||||||
private ComponentFlow.Builder componentFlowBuilder;
|
private ComponentFlow.Builder componentFlowBuilder;
|
||||||
|
|
||||||
public void runFlow() {
|
public void runFlow() {
|
||||||
Map<String, String> single1SelectItems = new HashMap<>();
|
List<SelectItem> single1SelectItems = Arrays.asList(SelectItem.of("key1", "value1"),
|
||||||
single1SelectItems.put("key1", "value1");
|
SelectItem.of("key2", "value2"));
|
||||||
single1SelectItems.put("key2", "value2");
|
|
||||||
List<SelectItem> multi1SelectItems = Arrays.asList(SelectItem.of("key1", "value1"),
|
List<SelectItem> multi1SelectItems = Arrays.asList(SelectItem.of("key1", "value1"),
|
||||||
SelectItem.of("key2", "value2"), SelectItem.of("key3", "value3"));
|
SelectItem.of("key2", "value2"), SelectItem.of("key3", "value3"));
|
||||||
ComponentFlow flow = componentFlowBuilder.clone().reset()
|
ComponentFlow flow = componentFlowBuilder.clone().reset()
|
||||||
|
|||||||
Reference in New Issue
Block a user