11package org .springframework .shell .core .command ;
22
3+ import java .lang .reflect .Method ;
4+ import java .lang .reflect .Type ;
5+ import java .util .ArrayList ;
6+ import java .util .Arrays ;
7+ import java .util .Collections ;
8+ import java .util .List ;
9+ import java .util .function .Consumer ;
10+ import java .util .function .Function ;
11+ import java .util .function .Supplier ;
12+
313import org .jspecify .annotations .Nullable ;
14+
415import org .springframework .core .ResolvableType ;
516import org .springframework .shell .core .command .availability .Availability ;
17+ import org .springframework .shell .core .command .metadata .CommandAlias ;
18+ import org .springframework .shell .core .command .metadata .CommandExitCode ;
19+ import org .springframework .shell .core .command .metadata .CommandHelpOptionInfo ;
620import org .springframework .shell .core .command .metadata .CommandOption ;
721import org .springframework .shell .core .command .metadata .CommandTarget ;
822import org .springframework .shell .core .command .metadata .CommandTarget .TargetType ;
1226import org .springframework .util .Assert ;
1327import org .springframework .util .ObjectUtils ;
1428import org .springframework .util .ReflectionUtils ;
15-
16- import java .lang .reflect .Method ;
17- import java .lang .reflect .Type ;
18- import java .util .ArrayList ;
19- import java .util .Arrays ;
20- import java .util .Collections ;
21- import java .util .List ;
22- import java .util .function .Consumer ;
23- import java .util .function .Function ;
24- import java .util .function .Supplier ;
25- import java .util .stream .Collectors ;
29+ import org .springframework .util .StringUtils ;
30+ import static java .util .stream .Collectors .*;
2631
2732class DefaultCommand implements Command {
2833
29- private String command ;
30-
31- private InteractionMode interactionMode ;
34+ private final String command ;
3235
33- private @ Nullable String group ;
36+ private final InteractionMode interactionMode ;
3437
35- private boolean hidden ;
38+ private final @ Nullable String group ;
3639
37- private @ Nullable String description ;
40+ private final boolean hidden ;
3841
39- private Supplier < Availability > availability ;
42+ private final @ Nullable String description ;
4043
41- private @ Nullable List < CommandOption > options ;
44+ private final Supplier < Availability > availability ;
4245
43- private List <DefaultOptionSpec > optionSpecs ;
46+ private final List <CommandOption > options ;
4447
45- private DefaultTargetSpec targetSpec ;
48+ private final DefaultTargetSpec targetSpec ;
4649
47- private List <DefaultAliasSpec > aliasSpecs ;
50+ private final List <DefaultAliasSpec > aliasSpecs ;
4851
49- private @ Nullable DefaultExitCodeSpec exitCodeSpec ;
52+ private final @ Nullable DefaultExitCodeSpec exitCodeSpec ;
5053
51- private @ Nullable DefaultErrorHandlingSpec errorHandlingSpec ;
54+ private final @ Nullable DefaultErrorHandlingSpec errorHandlingSpec ;
5255
53- private @ Nullable DefaultHelpOptionsSpec helpOptionsSpec ;
56+ private final @ Nullable DefaultHelpOptionsSpec helpOptionsSpec ;
5457
5558 private final @ Nullable Function <String , String > defaultOptionNameModifier ;
5659
@@ -65,7 +68,7 @@ public DefaultCommand(String command, InteractionMode interactionMode, @Nullable
6568 this .hidden = hidden ;
6669 this .description = description ;
6770 this .availability = availability ;
68- this .optionSpecs = optionSpecs ;
71+ this .options = initOptions ( optionSpecs ) ;
6972 this .targetSpec = targetSpec ;
7073 this .aliasSpecs = aliasSpecs ;
7174 this .exitCodeSpec = exitCodeSpec ;
@@ -101,35 +104,11 @@ public boolean isHidden() {
101104
102105 @ Override
103106 public Availability getAvailability () {
104- return availability != null ? availability .get () : Availability . available ();
107+ return availability .get ();
105108 }
106109
107110 @ Override
108111 public List <CommandOption > getOptions () {
109- if (options != null ) {
110- return options ;
111- }
112- options = optionSpecs .stream ().map (o -> {
113- String [] longNames = o .longNames ;
114- String [] longNamesModified = new String [0 ];
115- Function <String , String > modifier = o .nameModifier != null ? o .nameModifier : defaultOptionNameModifier ;
116- if (modifier != null ) {
117- longNamesModified = Arrays .copyOf (longNames , longNames .length );
118- longNames = Arrays .stream (longNames ).map (modifier ).toArray (String []::new );
119- }
120- return new CommandOption (longNames , longNamesModified , o .shortNames , o .description , o .type , o .required ,
121- o .defaultValue , o .position , o .arityMin , o .arityMax , o .label , o .completion );
122- }).collect (Collectors .toList ());
123-
124- if (helpOptionsSpec != null ) {
125- String [] longNames = helpOptionsSpec .longNames != null ? helpOptionsSpec .longNames : new String [0 ];
126- Character [] shortNames = helpOptionsSpec .shortNames != null ? helpOptionsSpec .shortNames : new Character [0 ];
127- String desc = "help for %s" .formatted (command );
128- CommandOption commandOption = CommandOption .of (longNames , shortNames , desc ,
129- ResolvableType .forType (void .class ));
130- options .add (commandOption );
131- }
132-
133112 return options ;
134113 }
135114
@@ -156,16 +135,19 @@ public CommandTarget getTarget() {
156135
157136 @ Override
158137 public List <CommandAlias > getAliases () {
159- return aliasSpecs .stream ().map (spec -> CommandAlias .of (spec .commands , spec .group )).toList ();
138+ return aliasSpecs .stream ()
139+ .filter (spec -> StringUtils .hasText (spec .commands ))
140+ .map (spec -> new CommandAlias (spec .commands , spec .group ))
141+ .toList ();
160142 }
161143
162144 @ Override
163145 public CommandExitCode getExitCode () {
164146 if (this .exitCodeSpec == null ) {
165- return CommandExitCode .of ();
147+ return CommandExitCode .empty ();
166148 }
167149 else {
168- return CommandExitCode . of (exitCodeSpec .functions );
150+ return new CommandExitCode (exitCodeSpec .functions );
169151 }
170152 }
171153
@@ -180,14 +162,39 @@ public List<CommandExceptionResolver> getExceptionResolvers() {
180162 }
181163
182164 @ Override
183- public HelpOptionInfo getHelpOption () {
165+ public CommandHelpOptionInfo getHelpOption () {
184166 if (this .helpOptionsSpec == null ) {
185- return HelpOptionInfo . of ();
167+ return CommandHelpOptionInfo . empty ();
186168 }
187169 else {
188- return HelpOptionInfo .of (helpOptionsSpec .enabled , helpOptionsSpec .longNames , helpOptionsSpec .shortNames ,
189- helpOptionsSpec .command );
170+ return new CommandHelpOptionInfo (helpOptionsSpec .enabled , helpOptionsSpec .longNames ,
171+ helpOptionsSpec .shortNames , helpOptionsSpec .command );
172+ }
173+ }
174+
175+ private List <CommandOption > initOptions (List <DefaultOptionSpec > optionSpecs ) {
176+ List <CommandOption > commandOptions = optionSpecs .stream ().map (o -> {
177+ String [] longNames = o .longNames ;
178+ String [] longNamesModified = new String [0 ];
179+ Function <String , String > modifier = o .nameModifier != null ? o .nameModifier : defaultOptionNameModifier ;
180+ if (modifier != null ) {
181+ longNamesModified = Arrays .copyOf (longNames , longNames .length );
182+ longNames = Arrays .stream (longNames ).map (modifier ).toArray (String []::new );
183+ }
184+ return new CommandOption (longNames , longNamesModified , o .shortNames , o .description , o .type , o .required ,
185+ o .defaultValue , o .position , o .arityMin , o .arityMax , o .label , o .completion );
186+ }).collect (toList ());
187+
188+ if (helpOptionsSpec != null ) {
189+ String [] longNames = helpOptionsSpec .longNames != null ? helpOptionsSpec .longNames : new String [0 ];
190+ Character [] shortNames = helpOptionsSpec .shortNames != null ? helpOptionsSpec .shortNames : new Character [0 ];
191+ String desc = "help for %s" .formatted (command );
192+ CommandOption commandOption = CommandOption .of (longNames , shortNames , desc ,
193+ ResolvableType .forType (void .class ));
194+ commandOptions .add (commandOption );
190195 }
196+
197+ return commandOptions ;
191198 }
192199
193200 static class DefaultOptionSpec implements OptionSpec {
0 commit comments