From 56dffe0223645f8533880196e49a77f8f2b5d02b Mon Sep 17 00:00:00 2001 From: Janne Valkealahti Date: Mon, 18 Dec 2023 10:03:36 +0000 Subject: [PATCH] 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 --- .../flow/BaseSingleItemSelector.java | 23 +++++++++---- .../shell/component/flow/ComponentFlow.java | 8 ++--- .../flow/SingleItemSelectorSpec.java | 14 ++++++-- .../component/flow/ComponentFlowTests.java | 34 ++++++++++++++++++- .../shell/docs/FlowComponentSnippets.java | 7 ++-- 5 files changed, 68 insertions(+), 18 deletions(-) diff --git a/spring-shell-core/src/main/java/org/springframework/shell/component/flow/BaseSingleItemSelector.java b/spring-shell-core/src/main/java/org/springframework/shell/component/flow/BaseSingleItemSelector.java index 0ba79d2c..73d0de27 100644 --- a/spring-shell-core/src/main/java/org/springframework/shell/component/flow/BaseSingleItemSelector.java +++ b/spring-shell-core/src/main/java/org/springframework/shell/component/flow/BaseSingleItemSelector.java @@ -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"); * 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.Comparator; -import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.function.Consumer; import java.util.function.Function; +import java.util.stream.Collectors; import org.jline.utils.AttributedString; @@ -40,7 +40,7 @@ public abstract class BaseSingleItemSelector extends BaseInput selectItems = new HashMap<>(); + private List selectItems = new ArrayList<>(); private String defaultSelect; private Comparator> comparator; private Function>, List> renderer; @@ -75,13 +75,22 @@ public abstract class BaseSingleItemSelector extends BaseInput selectItems) { - this.selectItems.putAll(selectItems); + List items = selectItems.entrySet().stream() + .map(e -> SelectItem.of(e.getKey(), e.getValue())) + .collect(Collectors.toList()); + selectItems(items); + return this; + } + + @Override + public SingleItemSelectorSpec selectItems(List selectItems) { + this.selectItems.addAll(selectItems); return this; } @@ -163,7 +172,7 @@ public abstract class BaseSingleItemSelector extends BaseInput getSelectItems() { + public List getSelectItems() { return selectItems; } @@ -202,4 +211,4 @@ public abstract class BaseSingleItemSelector extends BaseInput>, String> getNext() { return next; } -} \ No newline at end of file +} diff --git a/spring-shell-core/src/main/java/org/springframework/shell/component/flow/ComponentFlow.java b/spring-shell-core/src/main/java/org/springframework/shell/component/flow/ComponentFlow.java index d1ee2c83..b7a663e9 100644 --- a/spring-shell-core/src/main/java/org/springframework/shell/component/flow/ComponentFlow.java +++ b/spring-shell-core/src/main/java/org/springframework/shell/component/flow/ComponentFlow.java @@ -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"); * you may not use this file except in compliance with the License. @@ -565,9 +565,9 @@ public interface ComponentFlow { private Stream singleItemSelectorsStream() { return singleInputs.stream().map(input -> { - List> selectorItems = input.getSelectItems().entrySet().stream() - .map(e -> SelectorItem.of(e.getKey(), e.getValue())) - .collect(Collectors.toList()); + List> selectorItems = input.getSelectItems().stream() + .map(si -> SelectorItem.of(si.name(), si.item())) + .collect(Collectors.toList()); // setup possible item for initial expose String defaultSelect = input.getDefaultSelect(); diff --git a/spring-shell-core/src/main/java/org/springframework/shell/component/flow/SingleItemSelectorSpec.java b/spring-shell-core/src/main/java/org/springframework/shell/component/flow/SingleItemSelectorSpec.java index 4c5c4aa9..c57b713d 100644 --- a/spring-shell-core/src/main/java/org/springframework/shell/component/flow/SingleItemSelectorSpec.java +++ b/spring-shell-core/src/main/java/org/springframework/shell/component/flow/SingleItemSelectorSpec.java @@ -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"); * you may not use this file except in compliance with the License. @@ -65,6 +65,7 @@ public interface SingleItemSelectorSpec extends BaseInputSpec selectItems); + /** + * Adds a list of select items. + * + * @param selectItems the select items + * @return a builder + */ + SingleItemSelectorSpec selectItems(List selectItems); + /** * Automatically selects and exposes a given item. * @@ -156,4 +166,4 @@ public interface SingleItemSelectorSpec extends BaseInputSpec selectItems1 = Arrays.asList(SelectItem.of("key1", "value1"), SelectItem.of("key2", "value2")); + Map 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 field1 = (List) ReflectionTestUtils.getField(builder1, + "singleItemSelectors"); + List field2 = (List) ReflectionTestUtils.getField(builder2, + "singleItemSelectors"); + assertThat(field1).hasSize(1); + assertThat(field2).hasSize(1); + + List selectItems11 = (List) ReflectionTestUtils.getField(field1.get(0), "selectItems"); + List selectItems21 = (List) ReflectionTestUtils.getField(field2.get(0), "selectItems"); + assertThat(selectItems11).hasSize(2); + assertThat(selectItems21).hasSize(2); + } } diff --git a/spring-shell-docs/src/test/java/org/springframework/shell/docs/FlowComponentSnippets.java b/spring-shell-docs/src/test/java/org/springframework/shell/docs/FlowComponentSnippets.java index 1a26d5ed..fad1cc23 100644 --- a/spring-shell-docs/src/test/java/org/springframework/shell/docs/FlowComponentSnippets.java +++ b/spring-shell-docs/src/test/java/org/springframework/shell/docs/FlowComponentSnippets.java @@ -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"); * you may not use this file except in compliance with the License. @@ -33,9 +33,8 @@ public class FlowComponentSnippets { private ComponentFlow.Builder componentFlowBuilder; public void runFlow() { - Map single1SelectItems = new HashMap<>(); - single1SelectItems.put("key1", "value1"); - single1SelectItems.put("key2", "value2"); + List single1SelectItems = Arrays.asList(SelectItem.of("key1", "value1"), + SelectItem.of("key2", "value2")); List multi1SelectItems = Arrays.asList(SelectItem.of("key1", "value1"), SelectItem.of("key2", "value2"), SelectItem.of("key3", "value3")); ComponentFlow flow = componentFlowBuilder.clone().reset()