I want to accept a input with java.time.Duration data type in java using net.sourceforge.argparse4j.ArgumentParsers . However since Duration is a non-primitive data type, it is not directly supported to be passed as one of the argument. Is there any better or direct way to accept Duration as paramter in java other than specifying it as String in ISO-8601 format and using Duration.parse() (https://docs.oracle.com/javase/8/docs/api/java/time/Duration.html#parse-java.lang.CharSequence-) to convert it to Duration type.?
CodePudding user response:
The documentation says that it can convert to any object with a public static "valueOf(String)" method in addition to the primitives.
Duration is a final class, and does not have a "valueOf" method, just parse(), as you noted.
So TLDR; No.
CodePudding user response:
Seems ArgParse4j has no out-of-the box support for Java-Time classes but it offers 2 patterns that can be useful:
Creational pattern with valueOf
factory-method
Usually the T valueOf(String text)
factory-method is a very idiomatic creational pattern for text-parsing in Java.
If a class T
has no T valueOf(String)
method, you could just extend it and decorate it with the method.
Unfortunately the immutable java.time
types like java.time.Duration
are not designed to be extended or sub-typed - they are final
classes. So, I agree with GreyBeardedGeeks's answer.
Maybe the definition of a wrapper-class can help here to implement valueOf
together with a field of Duration
that is accessible.
Adapter pattern with convert
instance-method
Could also use a custom-type as converter or adapter, a class which implements ArgumentType<Duration>
and uses Duration.parse(CharSequence text)
to parse the ISO-8601 string and convert to the desired duration-type:
private static class IsoDurationArgument implements ArgumentType<Duration> {
@Override
public Duration convert(ArgumentParser parser, Argument arg, String value) throws ArgumentParserException {
try {
return Duration.parse(value); // the method you found
} catch (DateTimeParseException e) {
throw new ArgumentParserException(e, parser);
}
}
}
public static void main(String[] args) {
ArgumentParser parser = ArgumentParsers.newFor("prog").build();
parser.addArgument("duration").type(new IsoDurationArgument());
try {
System.out.println(parser.parseArgs(args));
} catch (ArgumentParserException e) {
parser.handleError(e);
}
}
Example copied and adapted from: The Argparse4j User Manual — Argument.type()
, search and scroll down to the example using a custom type PerfectSquare
:
The
Argument.type()
has a version which accepts an object which implementsArgumentType
interface