import javax.crypto.Cipher;
+
+class CipherConverter implements ITypeConverter<Cipher> {
+ public Cipher convert(String value) throws Exception {
+ return Cipher.getInstance(value);
+ }
+}
+diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index 59118678e..60b20a363 100644 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -26,6 +26,7 @@ Picocli follows [semantic versioning](http://semver.org/). * [#1304] DOC: Manual, chapter '17.9 Inherited Command Attributes': added Kotlin version of code sample. Thanks to [Andreas Deininger](https://github.com/deining) for the pull request. * [#1305] DOC: Document use of `IParameterConsumer` as n-ary type converter. Thanks to [Martin](https://github.com/martlin2cz) for raising this. * [#1307] DOC: Added CAUTION admonitions, Kotlin code sample. Thanks to [Andreas Deininger](https://github.com/deining) for the pull request. +* [#1308] DOC: Add example for Option `converter`. ## Deprecations No features were deprecated in this release. diff --git a/docs/index.html b/docs/index.html index 57d79561e..3fc50436f 100644 --- a/docs/index.html +++ b/docs/index.html @@ -3629,41 +3629,46 @@
Custom type converters can be registered with the CommandLine.registerConverter(Class<K> cls, ITypeConverter<K> converter)
method. All options and positional parameters with the specified type will be converted by the specified converter.
For example:
-- - | --Java 8 lambdas make it easy to register custom converters: - | -
import javax.crypto.Cipher;
+
+class CipherConverter implements ITypeConverter<Cipher> {
+ public Cipher convert(String value) throws Exception {
+ return Cipher.getInstance(value);
+ }
+}
+Custom type converters can be specified for a specific option or positional parameter with the converter
annotation attribute.
+This is described in more detail in the Option-specific Type Converters section, but here is a quick example:
CommandLine cl = new CommandLine(app);
-cl.registerConverter(Locale.class, s -> new Locale.Builder().setLanguageTag(s).build());
-cl.registerConverter(Cipher.class, s -> Cipher.getInstance(s));
+class App {
+ @Option(names = "-a", converter = CipherConverter.class)
+ javax.crypto.Cipher cipher;
+}
val cl = CommandLine(app)
-cl.registerConverter(Locale::class.java) {
- s: String? -> Locale.Builder().setLanguageTag(s).build()
-}
-cl.registerConverter(Cipher::class.java) {
- Cipher.getInstance(it)
-}
+class App {
+ @Option(names = ["-a"], converter = [CipherConverter::class])
+ lateinit var cipher: javax.crypto.Cipher
+}
Alternatively, custom type converters can be registered per type in each command with the CommandLine.registerConverter(Class<K> cls, ITypeConverter<K> converter)
method.
+All options and positional parameters with the specified type will be converted by the specified converter.
After registering custom converters, call the execute(String…)
or parseArgs(String…)
method on the CommandLine
instance where the converters are registered. (The static populateCommand
method cannot be used.) For example:
+ + | ++Java 8 lambdas make it easy to register custom converters: + | +
@Command(name = "set-position")
+class SetPositionCommand {
+ @Parameters(parameterConsumer = PointConverter::class)
+ private lateinit var position: Point
+
+ class PointConverter : IParameterConsumer {
+ override fun consumeParameters(args: Stack<String>,
+ argSpec: ArgSpec,
+ commandSpec: CommandSpec) {
+ if (args.size < 2) {
+ throw ParameterException(commandSpec.commandLine(),
+ "Missing coordinates for Point. Please specify 2 coordinates.")
+ }
+ val x = args.pop().toInt()
+ val y = args.pop().toInt()
+ argSpec.setValue(Point(x, y))
+ }
+ }
+}
+See the sections on Custom Parameter Processing for more details.
Type converters declared with the converter
attribute need to have a public no-argument constructor to be instantiated, unless a Custom Factory is installed to instantiate classes.
+ + | +
+If your type converter is declared as nested class, make sure you mark this class as static , or picocli will not be able to instantiate your nested converter class without a Custom Factory.
+ |
+
All transformers are called once, after the full command hierarchy is constructed, and before any command line arguments are parsed.
+ + | +
+If your model transformer is declared as nested class, make sure you mark this class as static , or picocli will not be able to instantiate your transformer class without a Custom Factory.
+ |
+
info.picocli:picocli
and the info.picocli:picocli-spring-boot-starter
dependencies.
Now open the pre-authored source file SpringBootDemoApplication.java
, rename it to MySpringMailer.java and edit and extend it so that it looks like this:
Now open the pre-authored source file SpringBootDemoApplication.java
, rename it to MySpringMailer.java
and edit and extend it so that it looks like this:
@org.springframework.stereotype.Component
annontation so that Spring can autodetect it for dependency injection.@org.springframework.stereotype.Component
annotation so that Spring can autodetect it for dependency injection.