From b5e26ab470c8a015a9da9d651e24a31e1292e991 Mon Sep 17 00:00:00 2001 From: sts Date: Mon, 18 Jul 2022 14:54:56 +0200 Subject: [PATCH 1/5] Added default selection to items --- .../shell/component/MultiItemSelector.java | 3 ++- .../shell/component/SingleItemSelector.java | 3 ++- .../shell/component/flow/ComponentFlow.java | 2 +- .../component/flow/DefaultSelectItem.java | 9 +++++++- .../shell/component/flow/SelectItem.java | 8 ++++--- .../support/AbstractSelectorComponent.java | 13 ++++++----- .../shell/component/support/Selectable.java | 6 +++++ .../shell/component/support/SelectorItem.java | 22 +++++++++++++------ .../component/MultiItemSelectorTests.java | 20 ++++++++++++++++- 9 files changed, 65 insertions(+), 21 deletions(-) create mode 100644 spring-shell-core/src/main/java/org/springframework/shell/component/support/Selectable.java diff --git a/spring-shell-core/src/main/java/org/springframework/shell/component/MultiItemSelector.java b/spring-shell-core/src/main/java/org/springframework/shell/component/MultiItemSelector.java index 081857354..2a1aebaca 100644 --- a/spring-shell-core/src/main/java/org/springframework/shell/component/MultiItemSelector.java +++ b/spring-shell-core/src/main/java/org/springframework/shell/component/MultiItemSelector.java @@ -32,6 +32,7 @@ import org.springframework.shell.component.support.Itemable; import org.springframework.shell.component.support.Matchable; import org.springframework.shell.component.support.Nameable; +import org.springframework.shell.component.support.Selectable; import org.springframework.shell.component.support.AbstractSelectorComponent.SelectorComponentContext; import org.springframework.shell.component.MultiItemSelector.MultiItemSelectorContext; @@ -40,7 +41,7 @@ * * @author Janne Valkealahti */ -public class MultiItemSelector> +public class MultiItemSelector> extends AbstractSelectorComponent, I> { private MultiItemSelectorContext currentContext; diff --git a/spring-shell-core/src/main/java/org/springframework/shell/component/SingleItemSelector.java b/spring-shell-core/src/main/java/org/springframework/shell/component/SingleItemSelector.java index a00eeaaec..b4ee86aa1 100644 --- a/spring-shell-core/src/main/java/org/springframework/shell/component/SingleItemSelector.java +++ b/spring-shell-core/src/main/java/org/springframework/shell/component/SingleItemSelector.java @@ -32,6 +32,7 @@ import org.springframework.shell.component.support.Itemable; import org.springframework.shell.component.support.Matchable; import org.springframework.shell.component.support.Nameable; +import org.springframework.shell.component.support.Selectable; import org.springframework.shell.component.support.AbstractSelectorComponent.SelectorComponentContext; import org.springframework.shell.component.SingleItemSelector.SingleItemSelectorContext; @@ -40,7 +41,7 @@ * * @author Janne Valkealahti */ -public class SingleItemSelector> +public class SingleItemSelector> extends AbstractSelectorComponent, I> { private SingleItemSelectorContext currentContext; 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 7bc9c9e99..777f5d6c9 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 @@ -617,7 +617,7 @@ private Stream singleItemSelectorsStream() { private Stream multiItemSelectorsStream() { return multiInputs.stream().map(input -> { List> selectorItems = input.getSelectItems().stream() - .map(si -> SelectorItem.of(si.name(), si.item(), si.enabled())) + .map(si -> SelectorItem.of(si.name(), si.item(), si.enabled(), si.selected())) .collect(Collectors.toList()); MultiItemSelector> selector = new MultiItemSelector<>(terminal, selectorItems, input.getName(), input.getComparator()); diff --git a/spring-shell-core/src/main/java/org/springframework/shell/component/flow/DefaultSelectItem.java b/spring-shell-core/src/main/java/org/springframework/shell/component/flow/DefaultSelectItem.java index 755f1f73a..b754d85c1 100644 --- a/spring-shell-core/src/main/java/org/springframework/shell/component/flow/DefaultSelectItem.java +++ b/spring-shell-core/src/main/java/org/springframework/shell/component/flow/DefaultSelectItem.java @@ -25,11 +25,13 @@ public class DefaultSelectItem implements SelectItem { private String name; private String item; private boolean enabled; + private boolean selected; - public DefaultSelectItem(String name, String item, boolean enabled) { + public DefaultSelectItem(String name, String item, boolean enabled, boolean selected) { this.name = name; this.item = item; this.enabled = enabled; + this.selected = selected; } @Override @@ -46,4 +48,9 @@ public String item() { public boolean enabled() { return enabled; } + + @Override + public boolean selected() { + return selected; + } } \ No newline at end of file diff --git a/spring-shell-core/src/main/java/org/springframework/shell/component/flow/SelectItem.java b/spring-shell-core/src/main/java/org/springframework/shell/component/flow/SelectItem.java index 120b41b3a..dd8364bde 100644 --- a/spring-shell-core/src/main/java/org/springframework/shell/component/flow/SelectItem.java +++ b/spring-shell-core/src/main/java/org/springframework/shell/component/flow/SelectItem.java @@ -43,11 +43,13 @@ public interface SelectItem { */ boolean enabled(); + boolean selected(); + public static SelectItem of(String name, String item) { - return of(name, item, true); + return of(name, item, true, false); } - public static SelectItem of(String name, String item, boolean enabled) { - return new DefaultSelectItem(name, item, enabled); + public static SelectItem of(String name, String item, boolean enabled, boolean selected) { + return new DefaultSelectItem(name, item, enabled, selected); } } \ No newline at end of file diff --git a/spring-shell-core/src/main/java/org/springframework/shell/component/support/AbstractSelectorComponent.java b/spring-shell-core/src/main/java/org/springframework/shell/component/support/AbstractSelectorComponent.java index 8e62ca2ae..07522058b 100644 --- a/spring-shell-core/src/main/java/org/springframework/shell/component/support/AbstractSelectorComponent.java +++ b/spring-shell-core/src/main/java/org/springframework/shell/component/support/AbstractSelectorComponent.java @@ -45,7 +45,7 @@ * * @author Janne Valkealahti */ -public abstract class AbstractSelectorComponent, I extends Nameable & Matchable & Enableable & Itemable> +public abstract class AbstractSelectorComponent, I extends Nameable & Matchable & Enableable & Selectable & Itemable> extends AbstractComponent { private final static Logger log = LoggerFactory.getLogger(AbstractSelectorComponent.class); @@ -257,7 +257,7 @@ private void initialExpose(C context) { AtomicInteger index = new AtomicInteger(0); itemStates = context.getItems().stream() .sorted(comparator) - .map(item -> ItemState.of(item, item.getName(), index.getAndIncrement(), item.isEnabled())) + .map(item -> ItemState.of(item, item.getName(), index.getAndIncrement(), item.isEnabled(), item.isSelected())) .collect(Collectors.toList()); } for (int i = 0; i < itemStates.size(); i++) { @@ -280,7 +280,7 @@ private ItemStateViewProjection buildItemStateView(int skip, SelectorComponentCo AtomicInteger index = new AtomicInteger(0); itemStates = context.getItems().stream() .sorted(comparator) - .map(item -> ItemState.of(item, item.getName(), index.getAndIncrement(), item.isEnabled())) + .map(item -> ItemState.of(item, item.getName(), index.getAndIncrement(), item.isEnabled(), item.isSelected())) .collect(Collectors.toList()); context.setItemStates(itemStates); } @@ -547,11 +547,12 @@ public static class ItemState implements Matchable { boolean enabled; int index; - ItemState(I item, String name, int index, boolean enabled) { + ItemState(I item, String name, int index, boolean enabled, boolean selected) { this.item = item; this.name = name; this.index = index; this.enabled = enabled; + this.selected = selected; } public boolean matches(String match) { @@ -574,8 +575,8 @@ public boolean isEnabled() { return enabled; } - static ItemState of(I item, String name, int index, boolean enabled) { - return new ItemState(item, name, index, enabled); + static ItemState of(I item, String name, int index, boolean enabled, boolean selected) { + return new ItemState(item, name, index, enabled, selected); } } diff --git a/spring-shell-core/src/main/java/org/springframework/shell/component/support/Selectable.java b/spring-shell-core/src/main/java/org/springframework/shell/component/support/Selectable.java new file mode 100644 index 000000000..2059a3513 --- /dev/null +++ b/spring-shell-core/src/main/java/org/springframework/shell/component/support/Selectable.java @@ -0,0 +1,6 @@ +package org.springframework.shell.component.support; + +public interface Selectable { + + boolean isSelected(); +} diff --git a/spring-shell-core/src/main/java/org/springframework/shell/component/support/SelectorItem.java b/spring-shell-core/src/main/java/org/springframework/shell/component/support/SelectorItem.java index 0ef0df5b1..91febf842 100644 --- a/spring-shell-core/src/main/java/org/springframework/shell/component/support/SelectorItem.java +++ b/spring-shell-core/src/main/java/org/springframework/shell/component/support/SelectorItem.java @@ -17,29 +17,31 @@ import org.springframework.util.StringUtils; -public interface SelectorItem extends Nameable, Matchable, Enableable, Itemable { +public interface SelectorItem extends Nameable, Matchable, Enableable, Selectable, Itemable { static SelectorItem of(String name, T item) { - return of(name, item, true); + return of(name, item, true, false); } - static SelectorItem of(String name, T item, boolean enabled) { - return new SelectorItemWrapper(name, item, enabled); + static SelectorItem of(String name, T item, boolean enabled, boolean selected) { + return new SelectorItemWrapper(name, item, enabled, selected); } public static class SelectorItemWrapper implements SelectorItem { private String name; private boolean enabled; private T item; + private boolean selected; public SelectorItemWrapper(String name, T item) { - this(name, item, true); + this(name, item, true, false); } - public SelectorItemWrapper(String name, T item, boolean enabled) { + public SelectorItemWrapper(String name, T item, boolean enabled, boolean selected) { this.name = name; this.item = item; this.enabled = enabled; + this.selected = selected; } @Override @@ -51,7 +53,7 @@ public String getName() { public boolean matches(String match) { if (!StringUtils.hasText(match)) { return true; - }; + } return name.toLowerCase().contains(match.toLowerCase()); } @@ -60,8 +62,14 @@ public boolean isEnabled() { return enabled; } + @Override public T getItem() { return item; } + + @Override + public boolean isSelected() { + return selected; + } } } diff --git a/spring-shell-core/src/test/java/org/springframework/shell/component/MultiItemSelectorTests.java b/spring-shell-core/src/test/java/org/springframework/shell/component/MultiItemSelectorTests.java index ce8031ac4..a6b004202 100644 --- a/spring-shell-core/src/test/java/org/springframework/shell/component/MultiItemSelectorTests.java +++ b/spring-shell-core/src/test/java/org/springframework/shell/component/MultiItemSelectorTests.java @@ -51,13 +51,15 @@ public class MultiItemSelectorTests extends AbstractShellTests { private static SimplePojo SIMPLE_POJO_5 = SimplePojo.of("data5"); private static SimplePojo SIMPLE_POJO_6 = SimplePojo.of("data6"); private static SimplePojo SIMPLE_POJO_7 = SimplePojo.of("data7"); + private static SimplePojo SIMPLE_POJO_8 = SimplePojo.of("data8"); private static SelectorItem SELECTOR_ITEM_1 = SelectorItem.of("simplePojo1", SIMPLE_POJO_1); private static SelectorItem SELECTOR_ITEM_2 = SelectorItem.of("simplePojo2", SIMPLE_POJO_2); private static SelectorItem SELECTOR_ITEM_3 = SelectorItem.of("simplePojo3", SIMPLE_POJO_3); private static SelectorItem SELECTOR_ITEM_4 = SelectorItem.of("simplePojo4", SIMPLE_POJO_4); private static SelectorItem SELECTOR_ITEM_5 = SelectorItem.of("simplePojo5", SIMPLE_POJO_5); private static SelectorItem SELECTOR_ITEM_6 = SelectorItem.of("simplePojo6", SIMPLE_POJO_6); - private static SelectorItem SELECTOR_ITEM_7 = SelectorItem.of("simplePojo7", SIMPLE_POJO_7, false); + private static SelectorItem SELECTOR_ITEM_7 = SelectorItem.of("simplePojo7", SIMPLE_POJO_7, false, false); + private static SelectorItem SELECTOR_ITEM_8 = SelectorItem.of("simplePojo8", SIMPLE_POJO_8, false, true); private ExecutorService service; private CountDownLatch latch; @@ -204,6 +206,22 @@ public void testSelectLastBackwards() throws InterruptedException { Stream datas = selected.stream().map(SelectorItem::getItem).map(SimplePojo::getData); assertThat(datas).containsExactlyInAnyOrder("data4"); } + + @Test + public void testDefaultSelection() throws InterruptedException { + scheduleSelect(Arrays.asList(SELECTOR_ITEM_1, SELECTOR_ITEM_2, SELECTOR_ITEM_7, SELECTOR_ITEM_8)); + + TestBuffer testBuffer = new TestBuffer().cr(); + write(testBuffer.getBytes()); + + awaitLatch(); + + List> selected = result.get(); + assertThat(selected).hasSize(1); + Stream datas = selected.stream().map(SelectorItem::getItem).map(SimplePojo::getData); + assertThat(datas).containsExactlyInAnyOrder("data8"); + assertThat(consoleOut()).contains("testSimple data8"); + } private void scheduleSelect() { scheduleSelect(Arrays.asList(SELECTOR_ITEM_1, SELECTOR_ITEM_2, SELECTOR_ITEM_3, From fafbc5ef284b2b9ce4d39bbc6ba9c315592adb52 Mon Sep 17 00:00:00 2001 From: sts Date: Mon, 18 Jul 2022 16:13:39 +0200 Subject: [PATCH 2/5] Added default selection to sample/doc code --- .../org/springframework/shell/docs/UiComponentSnippets.java | 2 +- .../shell/samples/standard/ComponentCommands.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/spring-shell-docs/src/test/java/org/springframework/shell/docs/UiComponentSnippets.java b/spring-shell-docs/src/test/java/org/springframework/shell/docs/UiComponentSnippets.java index c2570e1ef..806416e9f 100644 --- a/spring-shell-docs/src/test/java/org/springframework/shell/docs/UiComponentSnippets.java +++ b/spring-shell-docs/src/test/java/org/springframework/shell/docs/UiComponentSnippets.java @@ -170,7 +170,7 @@ public class ComponentCommands extends AbstractShellComponent { public String multiSelector() { List> items = new ArrayList<>(); items.add(SelectorItem.of("key1", "value1")); - items.add(SelectorItem.of("key2", "value2", false)); + items.add(SelectorItem.of("key2", "value2", false, true)); items.add(SelectorItem.of("key3", "value3")); MultiItemSelector> component = new MultiItemSelector<>(getTerminal(), items, "testSimple", null); diff --git a/spring-shell-samples/src/main/java/org/springframework/shell/samples/standard/ComponentCommands.java b/spring-shell-samples/src/main/java/org/springframework/shell/samples/standard/ComponentCommands.java index 832449531..11cc74fd3 100644 --- a/spring-shell-samples/src/main/java/org/springframework/shell/samples/standard/ComponentCommands.java +++ b/spring-shell-samples/src/main/java/org/springframework/shell/samples/standard/ComponentCommands.java @@ -93,7 +93,7 @@ public String singleSelector() { public String multiSelector() { List> items = new ArrayList<>(); items.add(SelectorItem.of("key1", "value1")); - items.add(SelectorItem.of("key2", "value2", false)); + items.add(SelectorItem.of("key2", "value2", false, true)); items.add(SelectorItem.of("key3", "value3")); MultiItemSelector> component = new MultiItemSelector<>(getTerminal(), items, "testSimple", null); From b2524bca13b325c54c53e38db20132bb10d49a53 Mon Sep 17 00:00:00 2001 From: Drevsh Date: Tue, 19 Jul 2022 20:53:55 +0200 Subject: [PATCH 3/5] Added missing javadoc --- .../org/springframework/shell/component/flow/SelectItem.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/spring-shell-core/src/main/java/org/springframework/shell/component/flow/SelectItem.java b/spring-shell-core/src/main/java/org/springframework/shell/component/flow/SelectItem.java index dd8364bde..436db2850 100644 --- a/spring-shell-core/src/main/java/org/springframework/shell/component/flow/SelectItem.java +++ b/spring-shell-core/src/main/java/org/springframework/shell/component/flow/SelectItem.java @@ -43,6 +43,11 @@ public interface SelectItem { */ boolean enabled(); + /** + * Return if the item is selected. + * + * @return if item is selected + */ boolean selected(); public static SelectItem of(String name, String item) { From 41d64a2d833da98ae5a3b685a2700ffad166ee67 Mon Sep 17 00:00:00 2001 From: Drevsh Date: Tue, 19 Jul 2022 20:54:16 +0200 Subject: [PATCH 4/5] Added missing license header --- .../shell/component/support/Selectable.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/spring-shell-core/src/main/java/org/springframework/shell/component/support/Selectable.java b/spring-shell-core/src/main/java/org/springframework/shell/component/support/Selectable.java index 2059a3513..17cadba60 100644 --- a/spring-shell-core/src/main/java/org/springframework/shell/component/support/Selectable.java +++ b/spring-shell-core/src/main/java/org/springframework/shell/component/support/Selectable.java @@ -1,3 +1,18 @@ +/* + * Copyright 2022 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. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.springframework.shell.component.support; public interface Selectable { From 4485a21b412a735b32830ad9d21d2ee889ada58c Mon Sep 17 00:00:00 2001 From: Drevsh Date: Tue, 19 Jul 2022 20:54:59 +0200 Subject: [PATCH 5/5] Added correct styling for disabled but default selected item --- .../shell/component/multi-item-selector-default.stg | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/spring-shell-core/src/main/resources/org/springframework/shell/component/multi-item-selector-default.stg b/spring-shell-core/src/main/resources/org/springframework/shell/component/multi-item-selector-default.stg index 599d83a9a..fd21c2261 100644 --- a/spring-shell-core/src/main/resources/org/springframework/shell/component/multi-item-selector-default.stg +++ b/spring-shell-core/src/main/resources/org/springframework/shell/component/multi-item-selector-default.stg @@ -18,7 +18,11 @@ select_item(item) ::= <% <({ }); format=selected_style(item.selected)> - <({ }); format="style-item-disabled"> + + <({ }); format="style-item-disabled"> + + <({ }); format="style-item-disabled"> + %>