0
# Type Conversion
1
2
Extensible type conversion system for converting string command line arguments to strongly typed Java objects, with built-in converters and custom converter support for complex data types.
3
4
## Capabilities
5
6
### Type Converter Interface
7
8
Core interface for implementing custom type converters that transform string arguments into typed values.
9
10
```java { .api }
11
/**
12
* Interface for converting string command line arguments to typed values
13
* @param <K> the target type
14
*/
15
public interface ITypeConverter<K> {
16
/**
17
* Converts a string value to the target type
18
* @param value the string value from command line
19
* @return the converted typed value
20
* @throws Exception if conversion fails
21
*/
22
K convert(String value) throws Exception;
23
}
24
25
/**
26
* Marker type converter indicating that the default converter should be used
27
*/
28
public static final class UseDefaultConverter implements ITypeConverter<Object> {
29
public Object convert(String value) throws Exception;
30
}
31
```
32
33
**Usage Examples:**
34
35
```java
36
// Custom converter for parsing date strings
37
public class DateConverter implements ITypeConverter<LocalDate> {
38
@Override
39
public LocalDate convert(String value) throws Exception {
40
return LocalDate.parse(value, DateTimeFormatter.ISO_LOCAL_DATE);
41
}
42
}
43
44
// Using custom converter in option
45
@Option(names = "--start-date",
46
converter = DateConverter.class,
47
description = "Start date in YYYY-MM-DD format")
48
LocalDate startDate;
49
50
// Custom converter for complex objects
51
public class PersonConverter implements ITypeConverter<Person> {
52
@Override
53
public Person convert(String value) throws Exception {
54
String[] parts = value.split(",");
55
if (parts.length != 2) {
56
throw new IllegalArgumentException("Expected format: name,age");
57
}
58
return new Person(parts[0], Integer.parseInt(parts[1]));
59
}
60
}
61
62
@Option(names = "--person",
63
converter = PersonConverter.class,
64
description = "Person in format: name,age")
65
Person person;
66
```
67
68
### Default Value Providers
69
70
Interface for providing default values for options and parameters, enabling dynamic defaults based on environment or configuration.
71
72
```java { .api }
73
/**
74
* Provides default values for options and parameters
75
*/
76
public interface IDefaultValueProvider {
77
/**
78
* Gets the default value for the specified argument
79
* @param argSpec the argument specification
80
* @return default value string or null if no default
81
* @throws Exception if default value calculation fails
82
*/
83
String defaultValue(ArgSpec argSpec) throws Exception;
84
}
85
86
/**
87
* Provides default values from properties files
88
*/
89
public static class PropertiesDefaultProvider implements IDefaultValueProvider {
90
/**
91
* Creates provider from properties file
92
* @param propertiesFile the properties file
93
*/
94
public PropertiesDefaultProvider(File propertiesFile);
95
96
/**
97
* Creates provider from properties
98
* @param properties the properties object
99
*/
100
public PropertiesDefaultProvider(Properties properties);
101
102
@Override
103
public String defaultValue(ArgSpec argSpec) throws Exception;
104
}
105
```
106
107
**Usage Examples:**
108
109
```java
110
// Environment-based default value provider
111
public class EnvironmentDefaultProvider implements IDefaultValueProvider {
112
@Override
113
public String defaultValue(ArgSpec argSpec) throws Exception {
114
if (argSpec.isOption()) {
115
OptionSpec option = (OptionSpec) argSpec;
116
// Map option names to environment variables
117
if (option.names().contains("--database-url")) {
118
return System.getenv("DATABASE_URL");
119
}
120
if (option.names().contains("--api-key")) {
121
return System.getenv("API_KEY");
122
}
123
}
124
return null; // No default available
125
}
126
}
127
128
// Using custom default provider
129
@Command(name = "app", defaultValueProvider = EnvironmentDefaultProvider.class)
130
class MyApp {
131
@Option(names = "--database-url") String databaseUrl;
132
@Option(names = "--api-key") String apiKey;
133
}
134
135
// Properties file default provider
136
Properties props = new Properties();
137
props.setProperty("output.directory", "/tmp/output");
138
props.setProperty("max.threads", "4");
139
140
CommandLine cmd = new CommandLine(new MyApp());
141
cmd.setDefaultValueProvider(new PropertiesDefaultProvider(props));
142
```
143
144
### Parameter Consumers
145
146
Advanced parameter processing interface for custom argument consumption patterns.
147
148
```java { .api }
149
/**
150
* Consumes command line arguments for options
151
*/
152
public interface IParameterConsumer {
153
/**
154
* Consumes parameters for the specified option
155
* @param stack the argument stack
156
* @param argSpec the argument specification
157
* @param commandSpec the command specification
158
* @throws Exception if consumption fails
159
*/
160
void consumeParameters(Stack<String> stack, ArgSpec argSpec, CommandSpec commandSpec) throws Exception;
161
}
162
```
163
164
**Usage Example:**
165
166
```java
167
// Custom parameter consumer for key=value pairs
168
public class KeyValueConsumer implements IParameterConsumer {
169
@Override
170
public void consumeParameters(Stack<String> stack, ArgSpec argSpec, CommandSpec commandSpec) throws Exception {
171
Map<String, String> map = new HashMap<>();
172
173
while (!stack.isEmpty() && !stack.peek().startsWith("-")) {
174
String arg = stack.pop();
175
String[] parts = arg.split("=", 2);
176
if (parts.length == 2) {
177
map.put(parts[0], parts[1]);
178
} else {
179
throw new ParameterException(commandSpec.commandLine(),
180
"Expected key=value format, got: " + arg);
181
}
182
}
183
184
argSpec.setValue(map);
185
}
186
}
187
188
@Option(names = "--properties",
189
parameterConsumer = KeyValueConsumer.class,
190
description = "Key-value pairs in format key1=value1 key2=value2")
191
Map<String, String> properties;
192
193
// Usage: --properties name=John age=30 city=Seattle
194
```
195
196
### Parameter Preprocessors
197
198
Interface for preprocessing command line arguments before parsing begins.
199
200
```java { .api }
201
/**
202
* Preprocesses command line arguments before parsing
203
*/
204
public interface IParameterPreprocessor {
205
/**
206
* Preprocesses the command line arguments
207
* @param args the original arguments
208
* @param commandSpec the command specification
209
* @return preprocessed arguments
210
*/
211
String[] preprocess(String[] args, CommandSpec commandSpec);
212
}
213
```
214
215
**Usage Example:**
216
217
```java
218
// Preprocessor that expands configuration files
219
public class ConfigFilePreprocessor implements IParameterPreprocessor {
220
@Override
221
public String[] preprocess(String[] args, CommandSpec commandSpec) {
222
List<String> expanded = new ArrayList<>();
223
224
for (String arg : args) {
225
if (arg.startsWith("@")) {
226
// Expand configuration file
227
String filename = arg.substring(1);
228
try {
229
List<String> fileArgs = Files.readAllLines(Paths.get(filename));
230
expanded.addAll(fileArgs);
231
} catch (IOException e) {
232
throw new ParameterException(commandSpec.commandLine(),
233
"Cannot read config file: " + filename);
234
}
235
} else {
236
expanded.add(arg);
237
}
238
}
239
240
return expanded.toArray(new String[0]);
241
}
242
}
243
244
// Usage: myapp @config.txt
245
// Where config.txt contains one argument per line
246
```
247
248
### Negatable Option Transformers
249
250
Interface for transforming negatable boolean options with custom patterns.
251
252
```java { .api }
253
/**
254
* Transforms negatable boolean options
255
*/
256
public interface INegatableOptionTransformer {
257
/**
258
* Creates a negated version of the option name
259
* @param optionName the original option name
260
* @param cmd the command line instance
261
* @return negated option name or null if not negatable
262
*/
263
String makeNegative(String optionName, CommandLine cmd);
264
265
/**
266
* Creates a synopsis for the negatable option
267
* @param optionName the option name
268
* @param cmd the command line instance
269
* @return synopsis text
270
*/
271
String makeSynopsis(String optionName, CommandLine cmd);
272
}
273
274
/**
275
* Regex-based negatable option transformer
276
*/
277
public static class RegexTransformer implements INegatableOptionTransformer {
278
/**
279
* Creates transformer with custom regex patterns
280
* @param negationPattern pattern for creating negated forms
281
* @param synopsisPattern pattern for synopsis generation
282
*/
283
public RegexTransformer(String negationPattern, String synopsisPattern);
284
285
@Override
286
public String makeNegative(String optionName, CommandLine cmd);
287
288
@Override
289
public String makeSynopsis(String optionName, CommandLine cmd);
290
}
291
```
292
293
**Usage Example:**
294
295
```java
296
// Custom negatable options
297
@Option(names = {"--enable-feature", "--disable-feature"},
298
negatable = true,
299
description = "Enable or disable the feature")
300
boolean featureEnabled;
301
302
// Custom transformer for different negation pattern
303
RegexTransformer transformer = new RegexTransformer(
304
"^--enable-(.*)$", "--disable-$1", // Transform --enable-X to --disable-X
305
"--[enable|disable]-$1" // Synopsis pattern
306
);
307
308
CommandLine cmd = new CommandLine(new MyApp());
309
cmd.setNegatableOptionTransformer(transformer);
310
311
// Usage: --enable-feature or --disable-feature
312
```
313
314
### Built-in Type Support
315
316
Picocli provides built-in type converters for common Java types without requiring custom converters.
317
318
```java { .api }
319
// Built-in types supported automatically:
320
// - All primitive types and their wrapper classes
321
// - String, StringBuilder, CharSequence
322
// - File, Path (java.nio.file.Path)
323
// - URL, URI
324
// - Pattern (java.util.regex.Pattern)
325
// - Enum types
326
// - Date and time types (java.time.* and java.util.Date)
327
// - Network types (InetAddress)
328
// - Arrays and Collections of supported types
329
// - BigInteger, BigDecimal
330
// - Currency, Locale, TimeZone, Charset
331
```
332
333
**Usage Examples:**
334
335
```java
336
@Command(name = "examples")
337
class TypeExamples {
338
// Primitive types
339
@Option(names = "--count") int count;
340
@Option(names = "--ratio") double ratio;
341
@Option(names = "--enabled") boolean enabled;
342
343
// File system
344
@Option(names = "--file") File file;
345
@Option(names = "--path") Path path;
346
347
// Network
348
@Option(names = "--url") URL url;
349
@Option(names = "--uri") URI uri;
350
@Option(names = "--host") InetAddress host;
351
352
// Time
353
@Option(names = "--date") LocalDate date;
354
@Option(names = "--time") LocalTime time;
355
@Option(names = "--instant") Instant instant;
356
357
// Collections
358
@Option(names = "--items") List<String> items;
359
@Option(names = "--numbers") int[] numbers;
360
361
// Enums
362
@Option(names = "--level") LogLevel level;
363
364
// Pattern matching
365
@Option(names = "--pattern") Pattern pattern;
366
367
// Locale and charset
368
@Option(names = "--locale") Locale locale;
369
@Option(names = "--charset") Charset charset;
370
}
371
372
enum LogLevel { DEBUG, INFO, WARN, ERROR }
373
```
374
375
### Range Type
376
377
Special type for representing arity ranges in option and parameter specifications.
378
379
```java { .api }
380
/**
381
* Represents an arity range for options and parameters
382
*/
383
public static class Range implements Comparable<Range> {
384
/**
385
* Creates a range with specified min and max values
386
* @param min minimum value (inclusive)
387
* @param max maximum value (inclusive)
388
*/
389
public Range(int min, int max);
390
391
/**
392
* Gets the minimum value
393
*/
394
public int min();
395
396
/**
397
* Gets the maximum value
398
*/
399
public int max();
400
401
/**
402
* Creates a range from string representation
403
* @param range string like "1..3", "2..*", "1"
404
*/
405
public static Range valueOf(String range);
406
407
/**
408
* Checks if a value is within this range
409
*/
410
public boolean contains(int value);
411
}
412
```
413
414
**Usage Example:**
415
416
```java
417
// Using Range for custom arity validation
418
@Option(names = "--files",
419
arity = "1..5", // Accept 1 to 5 files
420
description = "Input files (1-5 files)")
421
List<File> inputFiles;
422
423
@Parameters(arity = "2..*", // At least 2 parameters
424
description = "At least 2 output files required")
425
String[] outputFiles;
426
427
// Programmatic range usage
428
Range range = Range.valueOf("1..3");
429
if (range.contains(fileList.size())) {
430
System.out.println("Valid number of files");
431
}
432
```
433
434
### Additional Interfaces
435
436
Extended interfaces for advanced parameter processing and customization.
437
438
```java { .api }
439
/**
440
* Interface for consuming parameters from the command line arguments stack
441
*/
442
public interface IParameterConsumer {
443
/**
444
* Consumes parameters from the arguments stack
445
* @param args the arguments stack
446
* @param argSpec the argument specification
447
* @param commandSpec the command specification
448
*/
449
void consumeParameters(Stack<String> args, ArgSpec argSpec, CommandSpec commandSpec);
450
}
451
452
/**
453
* Interface for preprocessing parameters before consumption
454
*/
455
public interface IParameterPreprocessor {
456
/**
457
* Preprocesses a parameter before it is consumed
458
* @param args the arguments stack
459
* @param commandSpec the command specification
460
* @param argSpec the argument specification
461
* @param info additional preprocessing information
462
* @return true if preprocessing consumed the parameter, false otherwise
463
*/
464
boolean preprocess(Stack<String> args, CommandSpec commandSpec, ArgSpec argSpec, Map<String, Object> info);
465
}
466
467
/**
468
* Interface for transforming negatable option names
469
*/
470
public interface INegatableOptionTransformer {
471
/**
472
* Creates the negative form of an option name
473
* @param optionName the original option name
474
* @param cmd the command specification
475
* @return the negative option name
476
*/
477
String makeNegative(String optionName, CommandSpec cmd);
478
479
/**
480
* Creates the synopsis representation for negatable options
481
* @param optionName the original option name
482
* @param cmd the command specification
483
* @return the synopsis representation
484
*/
485
String makeSynopsis(String optionName, CommandSpec cmd);
486
}
487
```